openvibers/openvibe.shared Commits
4.26.1: an eyebrow led by the site's name keeps only what follows it (no name twice under the navbar) (#157)
Changes
@@@ -6,6 +6,13 @@ A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).## Unreleased++## 4.26.1 — 2026-10-28++++- **No site name twice:**++ - **The problem:** 14 homes opened with "OpenVibe.X · …" under a navbar that already says the name.++ - **The fix:** an eyebrow led by the site's name ("OpenVibe.Food · What should we eat?") now keeps only what follows it ("What should we eat?"), starting with a capital.++ - **Unchanged:** a name later in the phrase stays. An eyebrow that is only the name was already left out (4.23.0).++## 4.26.0 — 2026-10-28- **Every showcase hero gets a visual** (`showcase.js` `hero`; the owner, 2026-10-28: the heroes were "ugly af,@@@ -2,7 +2,7 @@> Versioned UI, the OpenVibe Frame (the navbar, footer and "shipped" views every site sits in), SEO, legal and release-client packages every OpenVibe site renders.--**Status:** alpha, v4.26.0 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed++**Status:** alpha, v4.26.1 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployedconsumer installs a tagged release and none keeps a vendored copy([docs/migration-plan.md](docs/migration-plan.md) is done); each repository's `package.json` namesthe tag it pins.@@@ -4,7 +4,7 @@"code": true,"wave": "W2","package": "openvibe-shared",-- "version": "4.26.0",++ "version": "4.26.1","plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)","deployed": false,"deployment": "none of its own: a package released as git tags; OpenVibe.Network serves /shared/* from its pinned tag, and a site can serve its own pinned copy (openvibe-shared/serve)",@@@ -1,6 +1,6 @@{"name": "openvibe-shared",-- "version": "4.26.0",++ "version": "4.26.1","description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site","main": "index.js","bin": {@@@ -56,10 +56,15 @@ function actions(list, cls = 'sc-actions') {// A site's own name as the eyebrow repeats the navbar's brand right above it ("OpenVibe.Quest" twice, the owner// 2026-10-28): such an eyebrow is left out. An eyebrow that says something else stays ({ icon, text } adds an icon).const SITE_NAME_RE = /^(?:OpenVibe\.[A-Za-z]+|OpenRestream|[A-Za-z]+\.OpenVibe\.[A-Za-z]+)$/;++// "OpenVibe.Food · What should we eat?": the name repeats the navbar's, so the eyebrow keeps only what follows it++// (4.26.1; the owner, 2026-10-28: "why is [the name] twice… in the navbar and then right after it").++const SITE_NAME_LEAD_RE = /^(?:OpenVibe\.[A-Za-z]+|OpenRestream|[A-Za-z]+\.OpenVibe\.[A-Za-z]+)\s*[·•|—–:-]\s*/;function eyebrowHTML(eyebrow) {const e = eyebrow && typeof eyebrow === 'object' ? eyebrow : { text: eyebrow };-- const text = String(e.text || '').trim();++ let text = String(e.text || '').trim();if (!text || SITE_NAME_RE.test(text)) return '';++ text = text.replace(SITE_NAME_LEAD_RE, '');++ text = text.charAt(0).toUpperCase() + text.slice(1);return `<p class="sc-eyebrow">${e.icon ? icon(e.icon, 16) : ''}${esc(text)}</p>`;}@@@ -143,4 +143,13 @@ assert.ok(/@container \(min-width:520px\) and \(max-width:1035px\)\{\.sc-grid:haassert.ok(/@media \(prefers-reduced-motion:reduce\)\{\.sc-ring,\.sc-aura-glow,\.sc-orb-ring,\.sc-orb-face\{animation:none\}\}/.test(sc.CSS), 'still under reduced motion');}++// The site's name leading an eyebrow is left out, the rest kept (4.26.1): 14 homes said "OpenVibe.X · …" under a navbar++// that already says it.++{++ assert.ok(/<p class="sc-eyebrow">What should we eat\?<\/p>/.test(sc.hero({ eyebrow: 'OpenVibe.Food · What should we eat?', title: 'T' })), 'the name leaves, the phrase stays');++ assert.ok(/<p class="sc-eyebrow">Open restreaming<\/p>/.test(sc.hero({ eyebrow: 'OpenRestream · open restreaming', title: 'T' })), 'and starts with a capital');++ assert.ok(/<p class="sc-eyebrow">Alpha<\/p>/.test(sc.hero({ eyebrow: 'OpenVibe.Bot · alpha', title: 'T' })));++ assert.ok(/<p class="sc-eyebrow">Free for OpenVibe\.Live streamers<\/p>/.test(sc.hero({ eyebrow: 'Free for OpenVibe.Live streamers', title: 'T' })), 'a name later in the phrase stays');++}++console.log('showcase: all checks passed');
@@ -6,6 +6,13 @@ A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
@@ -6,6 +6,13 @@ A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
## Unreleased
## Unreleased
+## 4.26.1 — 2026-10-28
+
+- **No site name twice:**
+ - **The problem:** 14 homes opened with "OpenVibe.X · …" under a navbar that already says the name.
+ - **The fix:** an eyebrow led by the site's name ("OpenVibe.Food · What should we eat?") now keeps only what follows it ("What should we eat?"), starting with a capital.
+ - **Unchanged:** a name later in the phrase stays. An eyebrow that is only the name was already left out (4.23.0).
+
## 4.26.0 — 2026-10-28
## 4.26.0 — 2026-10-28
- **Every showcase hero gets a visual** (`showcase.js` `hero`; the owner, 2026-10-28: the heroes were "ugly af,
- **Every showcase hero gets a visual** (`showcase.js` `hero`; the owner, 2026-10-28: the heroes were "ugly af,
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
> Versioned UI, the OpenVibe Frame (the navbar, footer and "shipped" views every site sits in), SEO, legal and release-client packages every OpenVibe site renders.
> Versioned UI, the OpenVibe Frame (the navbar, footer and "shipped" views every site sits in), SEO, legal and release-client packages every OpenVibe site renders.
-**Status:** alpha, v4.26.0 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed
+**Status:** alpha, v4.26.1 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed
consumer installs a tagged release and none keeps a vendored copy
consumer installs a tagged release and none keeps a vendored copy
([docs/migration-plan.md](docs/migration-plan.md) is done); each repository's `package.json` names
([docs/migration-plan.md](docs/migration-plan.md) is done); each repository's `package.json` names
the tag it pins.
the tag it pins.
@@ -4,7 +4,7 @@
@@ -4,7 +4,7 @@
"code": true,
"code": true,
"wave": "W2",
"wave": "W2",
"package": "openvibe-shared",
"package": "openvibe-shared",
- "version": "4.26.0",
+ "version": "4.26.1",
"plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)",
"plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)",
"deployed": false,
"deployed": false,
"deployment": "none of its own: a package released as git tags; OpenVibe.Network serves /shared/* from its pinned tag, and a site can serve its own pinned copy (openvibe-shared/serve)",
"deployment": "none of its own: a package released as git tags; OpenVibe.Network serves /shared/* from its pinned tag, and a site can serve its own pinned copy (openvibe-shared/serve)",
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-shared",
"name": "openvibe-shared",
- "version": "4.26.0",
+ "version": "4.26.1",
"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": {
@@ -56,10 +56,15 @@ function actions(list, cls = 'sc-actions') {
@@ -56,10 +56,15 @@ function actions(list, cls = 'sc-actions') {
// A site's own name as the eyebrow repeats the navbar's brand right above it ("OpenVibe.Quest" twice, the owner
// A site's own name as the eyebrow repeats the navbar's brand right above it ("OpenVibe.Quest" twice, the owner
// 2026-10-28): such an eyebrow is left out. An eyebrow that says something else stays ({ icon, text } adds an icon).
// 2026-10-28): such an eyebrow is left out. An eyebrow that says something else stays ({ icon, text } adds an icon).
const SITE_NAME_RE = /^(?:OpenVibe\.[A-Za-z]+|OpenRestream|[A-Za-z]+\.OpenVibe\.[A-Za-z]+)$/;
const SITE_NAME_RE = /^(?:OpenVibe\.[A-Za-z]+|OpenRestream|[A-Za-z]+\.OpenVibe\.[A-Za-z]+)$/;
+// "OpenVibe.Food · What should we eat?": the name repeats the navbar's, so the eyebrow keeps only what follows it
+// (4.26.1; the owner, 2026-10-28: "why is [the name] twice… in the navbar and then right after it").
+const SITE_NAME_LEAD_RE = /^(?:OpenVibe\.[A-Za-z]+|OpenRestream|[A-Za-z]+\.OpenVibe\.[A-Za-z]+)\s*[·•|—–:-]\s*/;
function eyebrowHTML(eyebrow) {
function eyebrowHTML(eyebrow) {
const e = eyebrow && typeof eyebrow === 'object' ? eyebrow : { text: eyebrow };
const e = eyebrow && typeof eyebrow === 'object' ? eyebrow : { text: eyebrow };
- const text = String(e.text || '').trim();
+ let text = String(e.text || '').trim();
if (!text || SITE_NAME_RE.test(text)) return '';
if (!text || SITE_NAME_RE.test(text)) return '';
+ text = text.replace(SITE_NAME_LEAD_RE, '');
+ text = text.charAt(0).toUpperCase() + text.slice(1);
return `<p class="sc-eyebrow">${e.icon ? icon(e.icon, 16) : ''}${esc(text)}</p>`;
return `<p class="sc-eyebrow">${e.icon ? icon(e.icon, 16) : ''}${esc(text)}</p>`;
}
}
@@ -143,4 +143,13 @@ assert.ok(/@container \(min-width:520px\) and \(max-width:1035px\)\{\.sc-grid:ha
@@ -143,4 +143,13 @@ assert.ok(/@container \(min-width:520px\) and \(max-width:1035px\)\{\.sc-grid:ha
assert.ok(/@media \(prefers-reduced-motion:reduce\)\{\.sc-ring,\.sc-aura-glow,\.sc-orb-ring,\.sc-orb-face\{animation:none\}\}/.test(sc.CSS), 'still under reduced motion');
assert.ok(/@media \(prefers-reduced-motion:reduce\)\{\.sc-ring,\.sc-aura-glow,\.sc-orb-ring,\.sc-orb-face\{animation:none\}\}/.test(sc.CSS), 'still under reduced motion');
}
}
+// The site's name leading an eyebrow is left out, the rest kept (4.26.1): 14 homes said "OpenVibe.X · …" under a navbar
+// that already says it.
+{
+ assert.ok(/<p class="sc-eyebrow">What should we eat\?<\/p>/.test(sc.hero({ eyebrow: 'OpenVibe.Food · What should we eat?', title: 'T' })), 'the name leaves, the phrase stays');
+ assert.ok(/<p class="sc-eyebrow">Open restreaming<\/p>/.test(sc.hero({ eyebrow: 'OpenRestream · open restreaming', title: 'T' })), 'and starts with a capital');
+ assert.ok(/<p class="sc-eyebrow">Alpha<\/p>/.test(sc.hero({ eyebrow: 'OpenVibe.Bot · alpha', title: 'T' })));
+ assert.ok(/<p class="sc-eyebrow">Free for OpenVibe\.Live streamers<\/p>/.test(sc.hero({ eyebrow: 'Free for OpenVibe.Live streamers', title: 'T' })), 'a name later in the phrase stays');
+}
+
console.log('showcase: all checks passed');
console.log('showcase: all checks passed');