openvibers/openvibe.network Commits

The bar sets itself up once navbar.js has run (signed-out visitors got the plain server row) (#862)

OP OpenVibers committed 24 h ago · aa39b45ca1 · 3 files, +28 −1

The home and the email check page load the shared navbar.js with defer but called OpenVibeNavbar.init at once.
For a signed-out visit navbar.js had not run yet, so the bar stayed the plain server row of links: unstyled, no menu
button, 30 px wider than a phone. Both now wait for the parse to finish; a test keeps every such page that way.

Changes

ddiff --git a/public/index.html b/public/index.html
iindex 1493a317..6e56f2b6 100644
---- a/public/index.html
++++ b/public/index.html
@@@ -289,6 +289,9 @@ footer{border-top:1px solid var(--border);background:var(--bg-secondary)}
const token = localStorage.getItem('ov_token') || getCookie('ov_token');
function initNavbar(user) {
++ // navbar.js is deferred: it runs after the page is parsed. A signed-out visit called this at once, before it had
++ // run, and the bar stayed the plain server row (2026-11-12). Until it is there, wait for the parse to finish.
++ if (typeof OpenVibeNavbar === 'undefined' && document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function () { initNavbar(user); }, { once: true }); return; }
if (typeof OpenVibeNavbar !== 'undefined') {
OpenVibeNavbar.init({ service: 'network', notificationsRealtime: true, token: token || null, user: user || null, menu: { before: [{ id: 'ov-wallet', label: 'Wallet', short: 'Wallet', icon: 'fa-wallet', href: 'https://openvibe.network/wallet' }] }, links: [{"label":"Network","href":"/"},{"label":"Link","href":"https://openvibe.link/","icon":"fa-desktop","featured":true},{"label":"My Account","href":"https://openvibe.my/"},{"label":"Wallet","href":"/wallet"},{"label":"Themes","href":"/themes"}], networkLinks: 5 });
}
ddiff --git a/public/verify-email.html b/public/verify-email.html
iindex ddcb5816..34ac3b5c 100644
---- a/public/verify-email.html
++++ b/public/verify-email.html
@@@ -96,7 +96,9 @@ p{color:var(--text-secondary);font-size:14px;line-height:1.6}
<script src="/js/account-safety.js" defer></script>
<script>
(function () {
-- if (window.OpenVibeNavbar) { try { OpenVibeNavbar.init({ service: 'network', apiBase: location.origin, links: [{"label":"Network","href":"/"},{"label":"Link","href":"https://openvibe.link/","icon":"fa-desktop","featured":true},{"label":"My Account","href":"https://openvibe.my/"},{"label":"Wallet","href":"/wallet"},{"label":"Themes","href":"/themes"}] }); } catch (e) { /* */ } }
++ // navbar.js is deferred: set the bar up once the page is parsed (it was called before navbar.js ran, 2026-11-12).
++ const setUpBar = () => { if (window.OpenVibeNavbar) { try { OpenVibeNavbar.init({ service: 'network', apiBase: location.origin, links: [{"label":"Network","href":"/"},{"label":"Link","href":"https://openvibe.link/","icon":"fa-desktop","featured":true},{"label":"My Account","href":"https://openvibe.my/"},{"label":"Wallet","href":"/wallet"},{"label":"Themes","href":"/themes"}] }); } catch (e) { /* */ } } };
++ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', setUpBar, { once: true }); else setUpBar();
const card = document.getElementById('card'), ring = document.getElementById('ring'), ico = document.getElementById('ico');
const title = document.getElementById('title'), msg = document.getElementById('msg'), actions = document.getElementById('actions'), hint = document.getElementById('hint');
const burst = document.getElementById('burst');
ddiff --git a/test/navbar-init-after-defer.test.js b/test/navbar-init-after-defer.test.js
nnew file mode 100644
iindex 00000000..dbd219ec
---- /dev/null
++++ b/test/navbar-init-after-defer.test.js
@@@ -0,0 +1,22 @@
++'use strict';
++// A page that loads the shared navbar.js with defer sets the bar up only once the page is parsed (2026-11-12: the home and
++// the email check page called OpenVibeNavbar.init at once; navbar.js had not run yet, so a signed-out visitor got the plain
++// server row of links, unstyled and wider than a phone). Each such page's setup waits for DOMContentLoaded or readyState.
++const assert = require('assert');
++const fs = require('fs');
++const path = require('path');
++
++const dir = path.join(__dirname, '..', 'public');
++const pages = fs.readdirSync(dir).filter((f) => f.endsWith('.html'));
++let checked = 0;
++pages.forEach((f) => {
++ const html = fs.readFileSync(path.join(dir, f), 'utf8');
++ if (!/<script src="\/shared\/navbar\.js" defer><\/script>/.test(html)) return;
++ const inline = [...html.matchAll(/<script>([\s\S]*?)<\/script>/g)].map((m) => m[1]).filter((js) => js.includes('OpenVibeNavbar.init('));
++ inline.forEach((js) => {
++ checked += 1;
++ assert.ok(/DOMContentLoaded/.test(js) && /readyState/.test(js), `${f}: the bar's setup waits until navbar.js (deferred) has run`);
++ });
++});
++assert.ok(checked >= 2, `the home and the email check page are among the pages checked (${checked})`);
++console.log(`navbar-init-after-defer: ${checked} page setups wait for the deferred navbar.js`);