fix(jellyfin): scope logo bocken.org link to home header only
The previous wrap-in-anchor approach leaked the bocken.org link onto unrelated page titles because Jellyfin reuses the same <h3> across navigations and only swaps its class between .pageTitleWithDefaultLogo and .pageTitle. Switch to click delegation so the redirect fires only when the clicked element currently carries the logo class. Also unwrap any legacy anchor wrappers on first mutation, and bump cursor/filter hover styles to !important so they survive Jellyfin's own h3 rules.
This commit is contained in:
@@ -233,15 +233,14 @@ progress[value]::-moz-progress-bar {
|
||||
background-image: url(https://bocken.org/static/css/logos/logo_full_light.png);
|
||||
}
|
||||
|
||||
/* Bocken logo link */
|
||||
.bocken-logo-link {
|
||||
display: flex;
|
||||
text-decoration: none;
|
||||
/* Bocken logo (clickable via JS click delegation) */
|
||||
.skinHeader:not(.osdHeader) .pageTitleWithDefaultLogo {
|
||||
cursor: pointer !important;
|
||||
transition: filter 150ms;
|
||||
}
|
||||
.bocken-logo-link:hover .pageTitleWithDefaultLogo {
|
||||
.skinHeader:not(.osdHeader) .pageTitleWithDefaultLogo:hover {
|
||||
/* Tint white logo to Nord lightblue (#81A1C1) */
|
||||
filter: brightness(0) saturate(100%) invert(61%) sepia(52%) saturate(212%) hue-rotate(169deg) brightness(92%) contrast(94%);
|
||||
filter: brightness(0) saturate(100%) invert(61%) sepia(52%) saturate(212%) hue-rotate(169deg) brightness(92%) contrast(94%) !important;
|
||||
}
|
||||
|
||||
/* Toast notification */
|
||||
|
||||
+41
-32
@@ -136,52 +136,61 @@
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
2. Make Bocken logo link to bocken.org
|
||||
Uses click delegation so we don't wrap the
|
||||
DOM — Jellyfin reuses the same <h3> across
|
||||
navigations and swaps its class between
|
||||
.pageTitleWithDefaultLogo (home) and
|
||||
.pageTitle (collection pages), which would
|
||||
leak the wrapper onto unrelated titles.
|
||||
═══════════════════════════════════════════ */
|
||||
(function () {
|
||||
function wrapLogo() {
|
||||
var logo = document.querySelector('.pageTitleWithDefaultLogo');
|
||||
if (!logo || logo.dataset.bockenLinked) return;
|
||||
logo.dataset.bockenLinked = '1';
|
||||
var isMobileApp = /wv\)|Jellyfin Mobile/.test(navigator.userAgent);
|
||||
|
||||
var isMobileApp = /wv\)|Jellyfin Mobile/.test(navigator.userAgent);
|
||||
/* One-time cleanup of legacy <a.bocken-logo-link> wrappers
|
||||
left behind by older versions of this script. */
|
||||
function unwrapLegacy() {
|
||||
document.querySelectorAll('a.bocken-logo-link').forEach(function (a) {
|
||||
while (a.firstChild) a.parentNode.insertBefore(a.firstChild, a);
|
||||
a.remove();
|
||||
});
|
||||
document.querySelectorAll('[data-bocken-linked]').forEach(function (el) {
|
||||
delete el.dataset.bockenLinked;
|
||||
});
|
||||
}
|
||||
|
||||
var link = document.createElement('a');
|
||||
link.href = 'https://bocken.org';
|
||||
link.className = 'bocken-logo-link';
|
||||
link.title = 'bocken.org';
|
||||
function openBocken() {
|
||||
if (isMobileApp) {
|
||||
link.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
navigator.clipboard.writeText('https://bocken.org').then(function () {
|
||||
var toast = document.createElement('div');
|
||||
toast.className = 'bocken-toast';
|
||||
toast.textContent = 'Link copied — open in browser';
|
||||
document.body.appendChild(toast);
|
||||
setTimeout(function () { toast.classList.add('bocken-toast-hide'); }, 2000);
|
||||
setTimeout(function () { toast.remove(); }, 2500);
|
||||
});
|
||||
navigator.clipboard.writeText('https://bocken.org').then(function () {
|
||||
var toast = document.createElement('div');
|
||||
toast.className = 'bocken-toast';
|
||||
toast.textContent = 'Link copied — open in browser';
|
||||
document.body.appendChild(toast);
|
||||
setTimeout(function () { toast.classList.add('bocken-toast-hide'); }, 2000);
|
||||
setTimeout(function () { toast.remove(); }, 2500);
|
||||
});
|
||||
} else {
|
||||
window.location.href = 'https://bocken.org';
|
||||
}
|
||||
logo.parentNode.insertBefore(link, logo);
|
||||
link.appendChild(logo);
|
||||
}
|
||||
|
||||
var pending = null;
|
||||
function schedule() {
|
||||
if (pending) return;
|
||||
pending = setTimeout(function () {
|
||||
pending = null;
|
||||
wrapLogo();
|
||||
}, 300);
|
||||
}
|
||||
document.addEventListener('click', function (e) {
|
||||
var logo = e.target.closest(
|
||||
'.skinHeader:not(.osdHeader) .pageTitleWithDefaultLogo'
|
||||
);
|
||||
if (!logo) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
openBocken();
|
||||
}, true);
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', schedule);
|
||||
document.addEventListener('DOMContentLoaded', unwrapLegacy);
|
||||
} else {
|
||||
schedule();
|
||||
unwrapLegacy();
|
||||
}
|
||||
|
||||
new MutationObserver(schedule).observe(document.body, {
|
||||
/* Catch wrappers that re-appear from cached SPA state */
|
||||
new MutationObserver(unwrapLegacy).observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user