commit 197907a3b30c4eb66168c0fef3da5116995e75bb
parent 41bdb62575e136e9907777483ce10dbb0d345bc4
Author: Hunter
Date:   Wed, 16 Jul 2025 15:53:14 -0400

inject fullscreen toggle button directly into preview pane iframe

Diffstat:
Mindex.html | 136++++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 73 insertions(+), 63 deletions(-)

diff --git a/index.html b/index.html @@ -50,49 +50,6 @@ position: relative; } - .fullscreen-toggle { - position: absolute; - top: 5px; - right: 5px; - z-index: 10000; - background: rgba(0, 0, 0, 0.2); - color: white; - border: none; - border-radius: 4px; - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: background-color 0.2s; - box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); - } - - .fullscreen-toggle.has-scrollbar { - right: calc(5px + env(scrollbar-width, 15px)); - } - - @media (pointer: none), (pointer: coarse) { - .fullscreen-toggle.has-scrollbar { - right: 5px; - } - } - - .fullscreen-toggle:hover { - background: rgba(0, 0, 0, 0.35); - } - - .fullscreen-toggle img { - filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.3)); - opacity: 0.8; - transition: opacity 0.2s; - } - - .fullscreen-toggle:hover img { - opacity: 1; - } - .preview-pane.fullscreen { position: fixed; top: 0; @@ -189,9 +146,6 @@ </div> <div class="preview-pane"> - <button class="fullscreen-toggle" id="fullscreenToggle" title="Toggle fullscreen"> - <img src="resources/fullscreen.svg" width="20" height="20" alt="Fullscreen"> - </button> <iframe id="preview"></iframe> </div> @@ -205,33 +159,54 @@ function toggleFullscreen() { const previewPane = document.querySelector('.preview-pane'); const editorPane = document.querySelector('.editor-pane'); - const toggleButton = document.getElementById('fullscreenToggle'); isFullscreen = !isFullscreen; if (isFullscreen) { previewPane.classList.add('fullscreen'); editorPane.classList.add('hidden'); - toggleButton.title = 'Exit fullscreen'; } else { previewPane.classList.remove('fullscreen'); editorPane.classList.remove('hidden'); - toggleButton.title = 'Toggle fullscreen'; + } + + // Update button title in iframe + try { + const toggleButton = preview.contentDocument.getElementById('fullscreenToggle'); + if (toggleButton) { + toggleButton.title = isFullscreen ? 'Exit fullscreen' : 'Toggle fullscreen'; + } + } catch (e) { + // Ignore cross-origin errors } } - document.addEventListener('DOMContentLoaded', function() { - const toggleButton = document.getElementById('fullscreenToggle'); - toggleButton.addEventListener('click', toggleFullscreen); - }); - function updateScrollbarDetection() { - const toggleButton = document.getElementById('fullscreenToggle'); + function createFullscreenToggle() { try { - if (preview.contentDocument && preview.contentDocument.body) { - const body = preview.contentDocument.body; - const hasScrollbar = body.scrollHeight > preview.clientHeight; - toggleButton.classList.toggle('has-scrollbar', hasScrollbar); + if (!preview.contentDocument) return; + + const doc = preview.contentDocument; + + // Remove existing button if it exists + const existingButton = doc.getElementById('fullscreenToggle'); + if (existingButton) { + existingButton.remove(); + } + + // Create button element + const button = doc.createElement('button'); + button.id = 'fullscreenToggle'; + button.className = 'iframe-fullscreen-toggle'; + button.title = 'Toggle fullscreen'; + button.innerHTML = `<img src="resources/fullscreen.svg" width="20" height="20" alt="Fullscreen">`; + + // Add click handler + button.addEventListener('click', toggleFullscreen); + + // Append to body + if (doc.body) { + doc.body.appendChild(button); } } catch (e) { // Ignore cross-origin errors @@ -257,9 +232,44 @@ doc.open(); doc.write(code); - // Inject CSS to disable overscroll in iframe content + // Inject CSS to disable overscroll and add fullscreen toggle styles const style = doc.createElement('style'); - style.textContent = `* { overscroll-behavior: none !important; }`; + style.textContent = ` + * { overscroll-behavior: none !important; } + + .iframe-fullscreen-toggle { + position: fixed; + top: 5px; + right: 5px; + z-index: 10000; + background: rgba(0, 0, 0, 0.2); + color: white; + border: none; + border-radius: 4px; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: background-color 0.2s; + box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); + } + + .iframe-fullscreen-toggle:hover { + background: rgba(0, 0, 0, 0.35); + } + + .iframe-fullscreen-toggle img { + filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.3)); + opacity: 0.8; + transition: opacity 0.2s; + } + + .iframe-fullscreen-toggle:hover img { + opacity: 1; + } + `; if (doc.head) { doc.head.appendChild(style); } @@ -275,8 +285,8 @@ } catch (e) { // Ignore cross-origin errors } - // Check for scrollbar after content is rendered - updateScrollbarDetection(); + // Create fullscreen toggle button after content is rendered + createFullscreenToggle(); }, 10); }