openvibers/openrestream Commits
Server-render the site navigation in the first HTML (#281)
Changes
@@@ -1,5 +1,6 @@'use strict';const ovServe = require('openvibe-shared/serve');++const frame = require('openvibe-shared/frame');const seo = require('openvibe-shared/seo');const social = require('openvibe-shared/social');const { TWIN_PATH_RE } = require('../agent-pages');@@@ -204,8 +205,7 @@ ${[...new Set(['showcase.css', 'kit.css', 'kit-data.css', ...styles])].map((name<script src="${ovServe.url('footer.js')}" defer></script></head><body>--<div id="navbar-mount"></div>--<noscript><nav class="ore" style="padding:8px 16px"><a href="/">OpenRestream</a> · <a href="/streams">Streams</a> · <a href="/sessions">Sessions</a> · ${user ? '<a href="/auth/logout">Sign out</a>' : '<a href="/auth/login">Sign in</a>'}</nav></noscript>++${frame.serverNav({ name: SITE, service: 'openre', home: '/', links: nav.links })}<main id="main" class="ore">${body}</main>@@@ -55,7 +55,10 @@ t('the UI works without JavaScript: landing, sign-in prompt, streams', async ()assert.strictEqual(home.status, 200);assert.match(home.text, /OpenRestream/);assert.match(home.text, /theme-loader\.js/);-- assert.match(home.text, /<noscript><nav/);++ // The first HTML carries the site navigation inside the mount (the browser navbar replaces it on boot).++ const serverNav = /<div id="navbar-mount"><nav[^>]*data-ov-server-nav="true"[\s\S]*?<\/nav><\/div>/.exec(home.text);++ assert.ok(serverNav, 'the first HTML has the server navigation');++ assert.match(serverNav[0], /href="\/streams"[^>]*>Streams</);const signin = await request(api.base, 'GET', '/streams');assert.strictEqual(signin.status, 401);assert.match(signin.text, /Sign in with OpenVibe/);@@@ -109,6 +109,11 @@ t('the front page leads with open restreaming, links to Live for browser go-liveconst r = await request(api.base, 'GET', '/');assert.strictEqual(r.status, 200);assert.match(r.text, /<h1>Go live once\. Stream everywhere\.<\/h1>/);++ // The first HTML carries the site's navigation, not only the scripts that draw it.++ const serverNav = /<div id="navbar-mount"><nav class="openvibe-navbar"[^>]*data-ov-server-nav="true"[\s\S]*?<\/nav><\/div>/.exec(r.text);++ assert.ok(serverNav, 'the first HTML has the server navigation');++ assert.match(serverNav[0], /href="\/streams"[^>]*>Streams</);++ assert.match(serverNav[0], /href="\/go-live"[^>]*>Go live</);assert.match(r.text, /ovk-page-head/);// The hero's signal flow (11-07): every platform with its own switch, the count by CSS, no script needed.const flow = (/<div class="ore-flow"[\s\S]*?<\/ul>/.exec(r.text) || [''])[0];
@@ -1,5 +1,6 @@
@@ -1,5 +1,6 @@
'use strict';
'use strict';
const ovServe = require('openvibe-shared/serve');
const ovServe = require('openvibe-shared/serve');
+const frame = require('openvibe-shared/frame');
const seo = require('openvibe-shared/seo');
const seo = require('openvibe-shared/seo');
const social = require('openvibe-shared/social');
const social = require('openvibe-shared/social');
const { TWIN_PATH_RE } = require('../agent-pages');
const { TWIN_PATH_RE } = require('../agent-pages');
@@ -204,8 +205,7 @@ ${[...new Set(['showcase.css', 'kit.css', 'kit-data.css', ...styles])].map((name
@@ -204,8 +205,7 @@ ${[...new Set(['showcase.css', 'kit.css', 'kit-data.css', ...styles])].map((name
<script src="${ovServe.url('footer.js')}" defer></script>
<script src="${ovServe.url('footer.js')}" defer></script>
</head>
</head>
<body>
<body>
-<div id="navbar-mount"></div>
-<noscript><nav class="ore" style="padding:8px 16px"><a href="/">OpenRestream</a> · <a href="/streams">Streams</a> · <a href="/sessions">Sessions</a> · ${user ? '<a href="/auth/logout">Sign out</a>' : '<a href="/auth/login">Sign in</a>'}</nav></noscript>
+${frame.serverNav({ name: SITE, service: 'openre', home: '/', links: nav.links })}
<main id="main" class="ore">
<main id="main" class="ore">
${body}
${body}
</main>
</main>
@@ -55,7 +55,10 @@ t('the UI works without JavaScript: landing, sign-in prompt, streams', async ()
@@ -55,7 +55,10 @@ t('the UI works without JavaScript: landing, sign-in prompt, streams', async ()
assert.strictEqual(home.status, 200);
assert.strictEqual(home.status, 200);
assert.match(home.text, /OpenRestream/);
assert.match(home.text, /OpenRestream/);
assert.match(home.text, /theme-loader\.js/);
assert.match(home.text, /theme-loader\.js/);
- assert.match(home.text, /<noscript><nav/);
+ // The first HTML carries the site navigation inside the mount (the browser navbar replaces it on boot).
+ const serverNav = /<div id="navbar-mount"><nav[^>]*data-ov-server-nav="true"[\s\S]*?<\/nav><\/div>/.exec(home.text);
+ assert.ok(serverNav, 'the first HTML has the server navigation');
+ assert.match(serverNav[0], /href="\/streams"[^>]*>Streams</);
const signin = await request(api.base, 'GET', '/streams');
const signin = await request(api.base, 'GET', '/streams');
assert.strictEqual(signin.status, 401);
assert.strictEqual(signin.status, 401);
assert.match(signin.text, /Sign in with OpenVibe/);
assert.match(signin.text, /Sign in with OpenVibe/);
@@ -109,6 +109,11 @@ t('the front page leads with open restreaming, links to Live for browser go-live
@@ -109,6 +109,11 @@ t('the front page leads with open restreaming, links to Live for browser go-live
const r = await request(api.base, 'GET', '/');
const r = await request(api.base, 'GET', '/');
assert.strictEqual(r.status, 200);
assert.strictEqual(r.status, 200);
assert.match(r.text, /<h1>Go live once\. Stream everywhere\.<\/h1>/);
assert.match(r.text, /<h1>Go live once\. Stream everywhere\.<\/h1>/);
+ // The first HTML carries the site's navigation, not only the scripts that draw it.
+ const serverNav = /<div id="navbar-mount"><nav class="openvibe-navbar"[^>]*data-ov-server-nav="true"[\s\S]*?<\/nav><\/div>/.exec(r.text);
+ assert.ok(serverNav, 'the first HTML has the server navigation');
+ assert.match(serverNav[0], /href="\/streams"[^>]*>Streams</);
+ assert.match(serverNav[0], /href="\/go-live"[^>]*>Go live</);
assert.match(r.text, /ovk-page-head/);
assert.match(r.text, /ovk-page-head/);
// The hero's signal flow (11-07): every platform with its own switch, the count by CSS, no script needed.
// The hero's signal flow (11-07): every platform with its own switch, the count by CSS, no script needed.
const flow = (/<div class="ore-flow"[\s\S]*?<\/ul>/.exec(r.text) || [''])[0];
const flow = (/<div class="ore-flow"[\s\S]*?<\/ul>/.exec(r.text) || [''])[0];