openvibers/openvibe.shared Commits
Shared 4.1.7: shell.page() removes the browser's body margin, so the Frame meets the window's edges (#75)
Changes
@@@ -4,6 +4,12 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semvebreaking change to any exported module, browser global or served file name is a new major.A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).++## 4.1.7 — 2026-10-15++++- **`shell.page()` removes the browser's body margin.** A site with no stylesheet of its own (openvibe.events,++ openvibe.bot) kept the default 8 px, so the Frame's footer stopped short of the window's edges. The head's reserved++ style now starts with `body{margin:0}`; sites that set it themselves are unchanged.++## 4.1.6 — 2026-10-15- **Play and Inventory show their own "Recently shipped".** `shipped.js` knew no `play` or `inventory` id, so the@@@ -1,6 +1,6 @@{"name": "openvibe-shared",-- "version": "4.1.6",++ "version": "4.1.7","description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site","main": "index.js","bin": {@@@ -114,8 +114,10 @@ function manifestLinks(o) {}// The shared navbar's script is deferred and mounts into the page's #navbar-mount: the mount holds the bar's 52px from--// the first paint so the page does not drop when it lands (layout shift), and without JavaScript it goes away.--const NAVBAR_RESERVE = '<style>#navbar-mount{min-height:52px}</style><noscript><style>#navbar-mount{display:none}</style></noscript>';++// the first paint so the page does not drop when it lands (layout shift), and without JavaScript it goes away. The body++// has no browser margin, so the Frame's navbar and footer meet the window's edges on a page with no stylesheet of its own++// (openvibe.events and openvibe.bot showed an 8px frame around the footer).++const NAVBAR_RESERVE = '<style>body{margin:0}#navbar-mount{min-height:52px}</style><noscript><style>#navbar-mount{display:none}</style></noscript>';function page(o = {}) {const name = o.name || o.service || 'OpenVibe';@@@ -27,7 +27,7 @@ assert.match(html, /<footer id="ov-footer"/, 'shared footer present');assert.ok(html.includes('<main id="hero">Hello</main>'), 'body kept verbatim');assert.ok(html.includes('<script src="/shared/theme-loader.js?v='), 'theme-loader via serve.url');// The deferred navbar lands in a #navbar-mount that already holds its height; without JavaScript the mount goes away.--assert.ok(html.includes('<style>#navbar-mount{min-height:52px}</style><noscript><style>#navbar-mount{display:none}</style></noscript>'), 'navbar mount reserved');++assert.ok(html.includes('<style>body{margin:0}#navbar-mount{min-height:52px}</style><noscript><style>#navbar-mount{display:none}</style></noscript>'), 'navbar mount reserved, and no browser margin around the body');assert.ok(html.indexOf('#navbar-mount{min-height:52px}') < html.indexOf('</head>'), 'in the head, before the first paint');// ── Script order: theme-loader first (eager); the runtime after it (deferred) ─────────────────────
@@ -4,6 +4,12 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semve
@@ -4,6 +4,12 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semve
breaking change to any exported module, browser global or served file name is a new major.
breaking change to any exported module, browser global or served file name is a new major.
A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
+## 4.1.7 — 2026-10-15
+
+- **`shell.page()` removes the browser's body margin.** A site with no stylesheet of its own (openvibe.events,
+ openvibe.bot) kept the default 8 px, so the Frame's footer stopped short of the window's edges. The head's reserved
+ style now starts with `body{margin:0}`; sites that set it themselves are unchanged.
+
## 4.1.6 — 2026-10-15
## 4.1.6 — 2026-10-15
- **Play and Inventory show their own "Recently shipped".** `shipped.js` knew no `play` or `inventory` id, so the
- **Play and Inventory show their own "Recently shipped".** `shipped.js` knew no `play` or `inventory` id, so the
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-shared",
"name": "openvibe-shared",
- "version": "4.1.6",
+ "version": "4.1.7",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"main": "index.js",
"main": "index.js",
"bin": {
"bin": {
@@ -114,8 +114,10 @@ function manifestLinks(o) {
@@ -114,8 +114,10 @@ function manifestLinks(o) {
}
}
// The shared navbar's script is deferred and mounts into the page's #navbar-mount: the mount holds the bar's 52px from
// The shared navbar's script is deferred and mounts into the page's #navbar-mount: the mount holds the bar's 52px from
-// the first paint so the page does not drop when it lands (layout shift), and without JavaScript it goes away.
-const NAVBAR_RESERVE = '<style>#navbar-mount{min-height:52px}</style><noscript><style>#navbar-mount{display:none}</style></noscript>';
+// the first paint so the page does not drop when it lands (layout shift), and without JavaScript it goes away. The body
+// has no browser margin, so the Frame's navbar and footer meet the window's edges on a page with no stylesheet of its own
+// (openvibe.events and openvibe.bot showed an 8px frame around the footer).
+const NAVBAR_RESERVE = '<style>body{margin:0}#navbar-mount{min-height:52px}</style><noscript><style>#navbar-mount{display:none}</style></noscript>';
function page(o = {}) {
function page(o = {}) {
const name = o.name || o.service || 'OpenVibe';
const name = o.name || o.service || 'OpenVibe';
@@ -27,7 +27,7 @@ assert.match(html, /<footer id="ov-footer"/, 'shared footer present');
@@ -27,7 +27,7 @@ assert.match(html, /<footer id="ov-footer"/, 'shared footer present');
assert.ok(html.includes('<main id="hero">Hello</main>'), 'body kept verbatim');
assert.ok(html.includes('<main id="hero">Hello</main>'), 'body kept verbatim');
assert.ok(html.includes('<script src="/shared/theme-loader.js?v='), 'theme-loader via serve.url');
assert.ok(html.includes('<script src="/shared/theme-loader.js?v='), 'theme-loader via serve.url');
// The deferred navbar lands in a #navbar-mount that already holds its height; without JavaScript the mount goes away.
// The deferred navbar lands in a #navbar-mount that already holds its height; without JavaScript the mount goes away.
-assert.ok(html.includes('<style>#navbar-mount{min-height:52px}</style><noscript><style>#navbar-mount{display:none}</style></noscript>'), 'navbar mount reserved');
+assert.ok(html.includes('<style>body{margin:0}#navbar-mount{min-height:52px}</style><noscript><style>#navbar-mount{display:none}</style></noscript>'), 'navbar mount reserved, and no browser margin around the body');
assert.ok(html.indexOf('#navbar-mount{min-height:52px}') < html.indexOf('</head>'), 'in the head, before the first paint');
assert.ok(html.indexOf('#navbar-mount{min-height:52px}') < html.indexOf('</head>'), 'in the head, before the first paint');
// ── Script order: theme-loader first (eager); the runtime after it (deferred) ─────────────────────
// ── Script order: theme-loader first (eager); the runtime after it (deferred) ─────────────────────