openvibers/openvibe.shared Commits
4.115.1: the Share sheet's headings ignore a site's own h2 rule (#298)
Changes
@@@ -1,5 +1,9 @@# Changelog++## 4.115.1 — 2026-11-06++++- **Share sheet:** its headings no longer take a site's own `h2` rule (Wiki's bottom border and margin showed under the sheet's title). Every property a site might set on an `h2` is reset inside the sheet and the access gate.++## 4.115.0 — 2026-11-06- **Locker in the browser** (`ov-locker.js`, `ov-locker.css`; plan Q2; docs/locker.md). The owner: "completely@@@ -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.115.0 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed++**Status:** alpha, v4.115.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.115.0",++ "version": "4.115.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)",@@@ -491,7 +491,7 @@const NAV_ICONS_REV = 'd9a4febbbad7'; // sha256(nav-icons.js), first 12 hex: its ?v= (cacheable forever)// END generated// The files loaded from beside this one, by content (scripts/sibling-revs.js): a release changes their URLs.-- const SIBLING_REV = { 'ov-mark.js': '1e91c9c0f347', 'ov-glyphs.js': '715972edd968', 'ov-brand.woff2': '3b4e6a8a5878', 'ov-look.js': '2a6c53a7b176', 'ov-fx.js': '46fce1e2b8db', 'ov-labels.js': 'a30b178391f5', 'ov-forms.js': '068ce1b1c4d5', 'ov-forms.css': '98cf0f28bb68', 'ov-share.js': 'd5bbb14b108e', 'ov-share.css': 'd6afb0f03db7' };++ const SIBLING_REV = { 'ov-mark.js': '1e91c9c0f347', 'ov-glyphs.js': '715972edd968', 'ov-brand.woff2': '3b4e6a8a5878', 'ov-look.js': '2a6c53a7b176', 'ov-fx.js': '46fce1e2b8db', 'ov-labels.js': 'a30b178391f5', 'ov-forms.js': '068ce1b1c4d5', 'ov-forms.css': '98cf0f28bb68', 'ov-share.js': 'd5bbb14b108e', 'ov-share.css': 'f694a088190f' };// The navbar's icons are filled paths (no Font Awesome CSS needed): the ones above ship here, the rest// (nav-icons.js) load after first paint when a link, chip or menu row names one, into an empty <svg> of their// size. Anything unknown, or nav-icons.js failing, falls back to <i class="fa-solid">.@@@ -32,6 +32,9 @@.ov-share::backdrop { background: rgb(6 10 16 / .52); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }html.ov-share-locked, html.ov-share-locked body { overflow: hidden; overscroll-behavior: none; }.ov-share-box { display: flex; flex-direction: column; max-height: inherit; min-height: 0; }++/* The sheet's headings are h2s on someone else's page: a site's own h2 rule (Wiki: a bottom border, a big margin) must++ not reach them. Every property a site might set on h2 is set here. */++.ov-share .ov-share-title, .ov-share-gate .ov-share-gatetitle { border: 0; padding: 0; background: none; color: inherit; font-family: inherit; text-transform: none; text-decoration: none; box-shadow: none; }.ov-share-head { display: flex; align-items: center; gap: 6px; padding: 14px 10px 6px 20px; }.ov-share-title { flex: 1; min-width: 0; margin: 0; font-size: 17px; font-weight: 700; line-height: 1.3; letter-spacing: -.005em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.ov-share-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: grid; align-content: start; gap: 18px; padding: 8px 20px 18px; scrollbar-width: thin; }@@@ -1,12 +1,12 @@{"name": "openvibe-shared",-- "version": "4.115.0",++ "version": "4.115.1","lockfileVersion": 3,"requires": true,"packages": {"": {"name": "openvibe-shared",-- "version": "4.115.0",++ "version": "4.115.1","license": "MIT","dependencies": {"jsonwebtoken": "^9.0.0",@@@ -1,6 +1,6 @@{"name": "openvibe-shared",-- "version": "4.115.0",++ "version": "4.115.1","description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site","main": "index.js","bin": {@@@ -100,6 +100,11 @@ const server = http.createServer((req, res) => {await wait(300);assert.strictEqual(await p.evaluate("document.querySelector('dialog.ov-share').open"), true, 'a [data-ov-share-sheet] button opens the sheet as a modal dialog');assert.strictEqual(await p.evaluate("document.getElementById('ov-share-title').textContent"), 'Share “<b>notes</b>”', 'the title is text, never markup');++ // A site's own h2 rule (Wiki: h2 { border-bottom; padding-bottom; margin }) never reaches the sheet's title.++ await p.evaluate("(() => { const st = document.createElement('style'); st.textContent = 'h2 { border-bottom: 3px solid red; padding-bottom: 9px; text-transform: uppercase; }'; document.head.appendChild(st); })()");++ assert.strictEqual(await p.evaluate("getComputedStyle(document.getElementById('ov-share-title')).borderBottomWidth"), '0px', 'a page h2 border does not reach the sheet title');++ assert.strictEqual(await p.evaluate("getComputedStyle(document.getElementById('ov-share-title')).paddingBottom"), '0px', 'nor its padding');++ assert.strictEqual(await p.evaluate("getComputedStyle(document.getElementById('ov-share-title')).textTransform"), 'none', 'nor its text-transform');assert.strictEqual(await p.evaluate(`${q('aud-private')}.checked`), true, 'the service\'s audience is chosen');assert.strictEqual(await p.evaluate("document.querySelector('dialog.ov-share [data-k=\"done\"]').textContent"), 'Done', 'nothing changed: Done, not Save');
@@ -1,5 +1,9 @@
@@ -1,5 +1,9 @@
# Changelog
# Changelog
+## 4.115.1 — 2026-11-06
+
+- **Share sheet:** its headings no longer take a site's own `h2` rule (Wiki's bottom border and margin showed under the sheet's title). Every property a site might set on an `h2` is reset inside the sheet and the access gate.
+
## 4.115.0 — 2026-11-06
## 4.115.0 — 2026-11-06
- **Locker in the browser** (`ov-locker.js`, `ov-locker.css`; plan Q2; docs/locker.md). The owner: "completely
- **Locker in the browser** (`ov-locker.js`, `ov-locker.css`; plan Q2; docs/locker.md). The owner: "completely
@@ -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.115.0 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed
+**Status:** alpha, v4.115.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.115.0",
+ "version": "4.115.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)",
@@ -491,7 +491,7 @@
@@ -491,7 +491,7 @@
const NAV_ICONS_REV = 'd9a4febbbad7'; // sha256(nav-icons.js), first 12 hex: its ?v= (cacheable forever)
const NAV_ICONS_REV = 'd9a4febbbad7'; // sha256(nav-icons.js), first 12 hex: its ?v= (cacheable forever)
// END generated
// END generated
// The files loaded from beside this one, by content (scripts/sibling-revs.js): a release changes their URLs.
// The files loaded from beside this one, by content (scripts/sibling-revs.js): a release changes their URLs.
- const SIBLING_REV = { 'ov-mark.js': '1e91c9c0f347', 'ov-glyphs.js': '715972edd968', 'ov-brand.woff2': '3b4e6a8a5878', 'ov-look.js': '2a6c53a7b176', 'ov-fx.js': '46fce1e2b8db', 'ov-labels.js': 'a30b178391f5', 'ov-forms.js': '068ce1b1c4d5', 'ov-forms.css': '98cf0f28bb68', 'ov-share.js': 'd5bbb14b108e', 'ov-share.css': 'd6afb0f03db7' };
+ const SIBLING_REV = { 'ov-mark.js': '1e91c9c0f347', 'ov-glyphs.js': '715972edd968', 'ov-brand.woff2': '3b4e6a8a5878', 'ov-look.js': '2a6c53a7b176', 'ov-fx.js': '46fce1e2b8db', 'ov-labels.js': 'a30b178391f5', 'ov-forms.js': '068ce1b1c4d5', 'ov-forms.css': '98cf0f28bb68', 'ov-share.js': 'd5bbb14b108e', 'ov-share.css': 'f694a088190f' };
// The navbar's icons are filled paths (no Font Awesome CSS needed): the ones above ship here, the rest
// The navbar's icons are filled paths (no Font Awesome CSS needed): the ones above ship here, the rest
// (nav-icons.js) load after first paint when a link, chip or menu row names one, into an empty <svg> of their
// (nav-icons.js) load after first paint when a link, chip or menu row names one, into an empty <svg> of their
// size. Anything unknown, or nav-icons.js failing, falls back to <i class="fa-solid">.
// size. Anything unknown, or nav-icons.js failing, falls back to <i class="fa-solid">.
@@ -32,6 +32,9 @@
@@ -32,6 +32,9 @@
.ov-share::backdrop { background: rgb(6 10 16 / .52); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
.ov-share::backdrop { background: rgb(6 10 16 / .52); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
html.ov-share-locked, html.ov-share-locked body { overflow: hidden; overscroll-behavior: none; }
html.ov-share-locked, html.ov-share-locked body { overflow: hidden; overscroll-behavior: none; }
.ov-share-box { display: flex; flex-direction: column; max-height: inherit; min-height: 0; }
.ov-share-box { display: flex; flex-direction: column; max-height: inherit; min-height: 0; }
+/* The sheet's headings are h2s on someone else's page: a site's own h2 rule (Wiki: a bottom border, a big margin) must
+ not reach them. Every property a site might set on h2 is set here. */
+.ov-share .ov-share-title, .ov-share-gate .ov-share-gatetitle { border: 0; padding: 0; background: none; color: inherit; font-family: inherit; text-transform: none; text-decoration: none; box-shadow: none; }
.ov-share-head { display: flex; align-items: center; gap: 6px; padding: 14px 10px 6px 20px; }
.ov-share-head { display: flex; align-items: center; gap: 6px; padding: 14px 10px 6px 20px; }
.ov-share-title { flex: 1; min-width: 0; margin: 0; font-size: 17px; font-weight: 700; line-height: 1.3; letter-spacing: -.005em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ov-share-title { flex: 1; min-width: 0; margin: 0; font-size: 17px; font-weight: 700; line-height: 1.3; letter-spacing: -.005em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ov-share-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: grid; align-content: start; gap: 18px; padding: 8px 20px 18px; scrollbar-width: thin; }
.ov-share-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: grid; align-content: start; gap: 18px; padding: 8px 20px 18px; scrollbar-width: thin; }
@@ -1,12 +1,12 @@
@@ -1,12 +1,12 @@
{
{
"name": "openvibe-shared",
"name": "openvibe-shared",
- "version": "4.115.0",
+ "version": "4.115.1",
"lockfileVersion": 3,
"lockfileVersion": 3,
"requires": true,
"requires": true,
"packages": {
"packages": {
"": {
"": {
"name": "openvibe-shared",
"name": "openvibe-shared",
- "version": "4.115.0",
+ "version": "4.115.1",
"license": "MIT",
"license": "MIT",
"dependencies": {
"dependencies": {
"jsonwebtoken": "^9.0.0",
"jsonwebtoken": "^9.0.0",
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-shared",
"name": "openvibe-shared",
- "version": "4.115.0",
+ "version": "4.115.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": {
@@ -100,6 +100,11 @@ const server = http.createServer((req, res) => {
@@ -100,6 +100,11 @@ const server = http.createServer((req, res) => {
await wait(300);
await wait(300);
assert.strictEqual(await p.evaluate("document.querySelector('dialog.ov-share').open"), true, 'a [data-ov-share-sheet] button opens the sheet as a modal dialog');
assert.strictEqual(await p.evaluate("document.querySelector('dialog.ov-share').open"), true, 'a [data-ov-share-sheet] button opens the sheet as a modal dialog');
assert.strictEqual(await p.evaluate("document.getElementById('ov-share-title').textContent"), 'Share “<b>notes</b>”', 'the title is text, never markup');
assert.strictEqual(await p.evaluate("document.getElementById('ov-share-title').textContent"), 'Share “<b>notes</b>”', 'the title is text, never markup');
+ // A site's own h2 rule (Wiki: h2 { border-bottom; padding-bottom; margin }) never reaches the sheet's title.
+ await p.evaluate("(() => { const st = document.createElement('style'); st.textContent = 'h2 { border-bottom: 3px solid red; padding-bottom: 9px; text-transform: uppercase; }'; document.head.appendChild(st); })()");
+ assert.strictEqual(await p.evaluate("getComputedStyle(document.getElementById('ov-share-title')).borderBottomWidth"), '0px', 'a page h2 border does not reach the sheet title');
+ assert.strictEqual(await p.evaluate("getComputedStyle(document.getElementById('ov-share-title')).paddingBottom"), '0px', 'nor its padding');
+ assert.strictEqual(await p.evaluate("getComputedStyle(document.getElementById('ov-share-title')).textTransform"), 'none', 'nor its text-transform');
assert.strictEqual(await p.evaluate(`${q('aud-private')}.checked`), true, 'the service\'s audience is chosen');
assert.strictEqual(await p.evaluate(`${q('aud-private')}.checked`), true, 'the service\'s audience is chosen');
assert.strictEqual(await p.evaluate("document.querySelector('dialog.ov-share [data-k=\"done\"]').textContent"), 'Done', 'nothing changed: Done, not Save');
assert.strictEqual(await p.evaluate("document.querySelector('dialog.ov-share [data-k=\"done\"]').textContent"), 'Done', 'nothing changed: Done, not Save');