diff --git a/shaarli-pro/js/script.js b/shaarli-pro/js/script.js index 5d12c9e..75af66d 100644 --- a/shaarli-pro/js/script.js +++ b/shaarli-pro/js/script.js @@ -1135,8 +1135,10 @@ document.addEventListener('DOMContentLoaded', () => { } }); - // ===== Persistent Media Player (Popup Strategy) ===== + // ===== Persistent Media Player (Popup via Blob URL) ===== // Audio plays in a separate popup window that survives page navigation. + // The popup HTML is generated as a Blob URL (no server file needed). + // Communication via BroadcastChannel API. // The inline bar serves as a "Now Playing" indicator and control relay. const MEDIA_EXTENSIONS = [ @@ -1146,10 +1148,10 @@ document.addEventListener('DOMContentLoaded', () => { function isMediaUrl(url) { if (!url) return false; - const lower = url.toLowerCase(); - const pathname = lower.split('?')[0].split('#')[0]; - for (const ext of MEDIA_EXTENSIONS) { - if (pathname.endsWith(ext)) return true; + var lower = url.toLowerCase(); + var pathname = lower.split('?')[0].split('#')[0]; + for (var i = 0; i < MEDIA_EXTENSIONS.length; i++) { + if (pathname.endsWith(MEDIA_EXTENSIONS[i])) return true; } if (/\/(stream|listen|live|icecast|shoutcast)(\/|$|\?)/i.test(url)) { return true; @@ -1157,474 +1159,596 @@ document.addEventListener('DOMContentLoaded', () => { return false; } - const playerBar = document.getElementById('media-player-bar'); - const playerPlayBtn = document.getElementById('media-player-play'); - const playerPlayIcon = document.getElementById('media-player-play-icon'); - const playerTitle = document.getElementById('media-player-title'); - const playerProgress = document.getElementById('media-player-progress'); - const playerTime = document.getElementById('media-player-time'); - const playerVolume = document.getElementById('media-player-volume'); - const playerVolBtn = document.getElementById('media-player-vol-btn'); - const playerVolIcon = document.getElementById('media-player-vol-icon'); - const playerCloseBtn = document.getElementById('media-player-close'); + var playerBar = document.getElementById('media-player-bar'); + var playerPlayBtn = document.getElementById('media-player-play'); + var playerPlayIcon = document.getElementById('media-player-play-icon'); + var playerTitle = document.getElementById('media-player-title'); + var playerProgress = document.getElementById('media-player-progress'); + var playerTime = document.getElementById('media-player-time'); + var playerVolume = document.getElementById('media-player-volume'); + var playerVolBtn = document.getElementById('media-player-vol-btn'); + var playerVolIcon = document.getElementById('media-player-vol-icon'); + var playerCloseBtn = document.getElementById('media-player-close'); // Reference to the popup window - let playerPopup = null; + var playerPopup = null; - /** - * Generate the full HTML for the popup player window. - * It is self-contained with its own styles and audio logic. - */ - function buildPopupHTML(url, title, volume) { + // BroadcastChannel for reliable cross-window communication + var playerChannel = null; + try { + playerChannel = new BroadcastChannel('shaarli-media-player'); + } catch (e) { + // BroadcastChannel not supported + } + + function buildPlayerHTML() { const isDark = document.documentElement.getAttribute('data-theme') === 'dark'; - const escapedTitle = title.replace(/'/g, "\\'").replace(/"/g, '"'); - const escapedUrl = url.replace(/'/g, "\\'").replace(/"/g, '"'); - - return ` - - - - -♪ ${escapedTitle} - - - - -
-
- - LIVE -
-
${escapedTitle}
-
- -
- 0:00 - 0:00 -
-
-
- - - -
-
- - - -
-
- - - -`; + const theme = isDark ? 'dark' : 'light'; + var lines = []; + lines.push(''); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push('♪ Shaarli Player'); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push('
'); + lines.push('
'); + lines.push(' '); + lines.push(' LIVE'); + lines.push('
'); + lines.push('
Loading...
'); + lines.push('
'); + lines.push(' '); + lines.push('
'); + lines.push(' 0:00'); + lines.push(' 0:00'); + lines.push('
'); + lines.push('
'); + lines.push('
'); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push('
'); + lines.push('
'); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push('
'); + lines.push('
'); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push(' + +