diff --git a/static/js/embed.js b/static/js/embed.js new file mode 100644 index 0000000..e36c3d6 --- /dev/null +++ b/static/js/embed.js @@ -0,0 +1,129 @@ +// Embed functionality for Sunday Comics +// Handles showing embed code modal and copying to clipboard + +(function() { + 'use strict'; + + const modal = document.getElementById('embed-modal'); + const embedButton = document.getElementById('embed-button'); + const closeButton = modal ? modal.querySelector('.modal-close') : null; + const embedCodeTextarea = document.getElementById('embed-code'); + const copyButton = document.getElementById('copy-embed-code'); + const previewLink = document.getElementById('embed-preview-link'); + + if (!modal || !embedButton) { + // Embed feature not enabled or elements not found + return; + } + + // Get the site URL from the page (we'll add it as a data attribute) + const siteUrl = document.body.getAttribute('data-site-url') || window.location.origin; + + // Open modal when embed button is clicked + embedButton.addEventListener('click', function() { + const comicNumber = this.getAttribute('data-comic-number'); + if (!comicNumber) return; + + // Generate embed code + const embedUrl = `${siteUrl}/embed/${comicNumber}`; + const embedCode = ``; + + // Set the embed code in the textarea + embedCodeTextarea.value = embedCode; + + // Set the preview link + previewLink.href = embedUrl; + + // Show the modal + modal.style.display = 'block'; + modal.setAttribute('aria-hidden', 'false'); + + // Focus on the textarea + embedCodeTextarea.focus(); + embedCodeTextarea.select(); + }); + + // Close modal when close button is clicked + if (closeButton) { + closeButton.addEventListener('click', function() { + closeModal(); + }); + } + + // Close modal when clicking outside the modal content + modal.addEventListener('click', function(event) { + if (event.target === modal) { + closeModal(); + } + }); + + // Close modal with Escape key + document.addEventListener('keydown', function(event) { + if (event.key === 'Escape' && modal.style.display === 'block') { + closeModal(); + } + }); + + // Copy embed code to clipboard + if (copyButton) { + copyButton.addEventListener('click', function() { + embedCodeTextarea.select(); + embedCodeTextarea.setSelectionRange(0, 99999); // For mobile devices + + try { + // Modern clipboard API + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(embedCodeTextarea.value).then(function() { + showCopyFeedback(); + }).catch(function() { + // Fallback to execCommand + fallbackCopy(); + }); + } else { + // Fallback for older browsers + fallbackCopy(); + } + } catch (err) { + fallbackCopy(); + } + }); + } + + function fallbackCopy() { + try { + document.execCommand('copy'); + showCopyFeedback(); + } catch (err) { + alert('Failed to copy. Please select and copy manually.'); + } + } + + function showCopyFeedback() { + const originalText = copyButton.textContent; + copyButton.textContent = 'Copied!'; + copyButton.classList.add('copied'); + + setTimeout(function() { + copyButton.textContent = originalText; + copyButton.classList.remove('copied'); + }, 2000); + } + + function closeModal() { + modal.style.display = 'none'; + modal.setAttribute('aria-hidden', 'true'); + + // Return focus to the embed button + if (embedButton) { + embedButton.focus(); + } + } + + // Update embed button when comic changes via client-side navigation + // This integrates with the existing comic-nav.js functionality + window.addEventListener('comicUpdated', function(event) { + if (event.detail && event.detail.comicNumber && embedButton) { + embedButton.setAttribute('data-comic-number', event.detail.comicNumber); + } + }); +})(); diff --git a/templates/embed.html b/templates/embed.html new file mode 100644 index 0000000..b81b937 --- /dev/null +++ b/templates/embed.html @@ -0,0 +1,156 @@ + + +
+ + +