openvibers/openvibe.media Commits

The index page carries the default theme tokens too (ADR-024): browse.js writes its own <style>, which now starts with openvibe-shared's DEFAULT_VARS (exported from page-frame as DEFAULT_THEME_CSS)

OP OpenVibers committed 26 Sept 2026 · 25ee3187d5 · 3 files, +6 −2


Changes

ddiff --git a/server/public/browse.js b/server/public/browse.js
iindex 010b0f6..26d7c04 100644
---- a/server/public/browse.js
++++ b/server/public/browse.js
@@@ -18,7 +18,7 @@ const PAGE_SIZE = 48;
const THUMB_DIR = path.resolve(config.thumbnails.path);
// Public base URL per app for "source" links — shared with the watch/paste pages.
--const { appUrl } = require('./page-frame');
++const { appUrl, DEFAULT_THEME_CSS } = require('./page-frame');
const frame = require('openvibe-shared/frame');
const esc = (s) => String(s ?? '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
@@@ -242,6 +242,7 @@ function renderPage(tab, page, data, counts) {
<!-- The shared theme-loader applies the user's theme to <html> before anything paints. -->
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<style>
++${DEFAULT_THEME_CSS ? `:root{${DEFAULT_THEME_CSS}}` : ''}
:root{--bg:var(--bg-primary,#0a0f1c);--panel:var(--bg-card,#131c2e);--border:#1f2d47;--text:var(--text-primary,#e6edf7);--muted:var(--text-secondary,#96a7c2);--accent-page:var(--accent,#3b82f6)}
*{box-sizing:border-box;margin:0}body{background:var(--bg);color:var(--text);font:15px/1.5 system-ui,'Segoe UI',Arial,sans-serif;padding-bottom:3rem}
header.intro{display:flex;align-items:baseline;gap:.2rem .8rem;flex-wrap:wrap;padding:1rem 1.4rem .4rem}
ddiff --git a/server/public/page-frame.js b/server/public/page-frame.js
iindex 0e4ba01..61510af 100644
---- a/server/public/page-frame.js
++++ b/server/public/page-frame.js
@@@ -213,5 +213,5 @@ ${frameScripts({ history, footer })}
module.exports = {
NETWORK_URL, SITE_NAME, DEFAULT_OG_IMAGE, APP_PUBLIC_URLS, appUrl,
esc, abs, snip, isoDate, isoDuration, fmtDuration, fmtDate, jsonForScript,
-- headTags, baseCss, frameScripts, defaultFooterLinks, page,
++ headTags, baseCss, frameScripts, defaultFooterLinks, page, DEFAULT_THEME_CSS,
};
ddiff --git a/test/theme-default.test.js b/test/theme-default.test.js
iindex bd02139..161017d 100644
---- a/test/theme-default.test.js
++++ b/test/theme-default.test.js
@@@ -12,4 +12,7 @@ for (const k of ['--accent', '--bg-primary', '--text-primary']) {
assert.ok(css.includes(`${k}:${DEFAULT_VARS[k]}`), `the page defines ${k} as the default theme does`);
}
assert.ok(!/url\(|;\s*}/.test(css.split('\n').find((l) => l.includes('--accent:')) || ''), 'only plain token values');
++// The index page (browse.js) writes its own <style>: it carries the same tokens.
++const src = require('fs').readFileSync(require('path').join(__dirname, '..', 'server', 'public', 'browse.js'), 'utf8');
++assert.ok(/<style>\n\$\{DEFAULT_THEME_CSS \?/.test(src), 'browse.js puts the default tokens first in its style');
console.log('theme default: all checks passed');