Last active
August 11, 2025 09:01
-
-
Save DiyarD/98e0396a401e8c9e456629e923801e65 to your computer and use it in GitHub Desktop.
Redirect Reddit media wrapper to data URL for native browser image viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Reddit Direct Image Data URL | |
| // @namespace http://tampermonkey.net/ | |
| // @version 1.1 | |
| // @description Redirect Reddit media wrapper to data URL for native browser image viewing | |
| // @author You | |
| // @match https://www.reddit.com/media* | |
| // @match https://reddit.com/media* | |
| // @grant GM_xmlhttpRequest | |
| // @run-at document-start | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| // Get the image URL from parameters immediately | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const imageUrl = urlParams.get('url'); | |
| if (!imageUrl) { | |
| return; // Let the page load normally if no image URL | |
| } | |
| const decodedUrl = decodeURIComponent(imageUrl); | |
| // Wait for DOM to be ready before modifying content | |
| const showLoadingAndFetch = () => { | |
| // Stop any further loading | |
| window.stop(); | |
| // Create loading page | |
| document.documentElement.innerHTML = ` | |
| <head> | |
| <title>Loading Image...</title> | |
| <style> | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| background: #1a1a1a; | |
| color: #fff; | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| min-height: 100vh; | |
| } | |
| .spinner { | |
| width: 40px; | |
| height: 40px; | |
| border: 4px solid #333; | |
| border-top: 4px solid #ff4500; | |
| border-radius: 50%; | |
| animation: spin 1s linear infinite; | |
| margin-bottom: 20px; | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| .url { | |
| font-size: 12px; | |
| color: #888; | |
| margin-top: 10px; | |
| word-break: break-all; | |
| max-width: 80%; | |
| text-align: center; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="spinner"></div> | |
| <h2>Loading Image...</h2> | |
| <div class="url">${decodedUrl}</div> | |
| </body> | |
| `; | |
| // Now fetch the image | |
| GM_xmlhttpRequest({ | |
| method: 'GET', | |
| url: decodedUrl, | |
| headers: { | |
| 'Referer': 'https://www.reddit.com/', | |
| 'User-Agent': navigator.userAgent, | |
| 'Accept': 'image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8' | |
| }, | |
| responseType: 'arraybuffer', | |
| onload: function(response) { | |
| if (response.status === 200) { | |
| // Convert arraybuffer to base64 | |
| const bytes = new Uint8Array(response.response); | |
| let binary = ''; | |
| for (let i = 0; i < bytes.byteLength; i++) { | |
| binary += String.fromCharCode(bytes[i]); | |
| } | |
| const base64 = btoa(binary); | |
| // Determine MIME type | |
| let mimeType = response.responseHeaders.match(/content-type:\s*([^;\r\n]+)/i)?.[1]; | |
| if (!mimeType) { | |
| const ext = decodedUrl.split('.').pop().toLowerCase().split('?')[0]; | |
| const mimeTypes = { | |
| 'jpg': 'image/jpeg', | |
| 'jpeg': 'image/jpeg', | |
| 'png': 'image/png', | |
| 'gif': 'image/gif', | |
| 'webp': 'image/webp', | |
| 'svg': 'image/svg+xml', | |
| 'bmp': 'image/bmp' | |
| }; | |
| mimeType = mimeTypes[ext] || 'image/jpeg'; | |
| } | |
| // Create data URL and redirect | |
| const dataUrl = `data:${mimeType};base64,${base64}`; | |
| window.location.replace(dataUrl); | |
| } else { | |
| document.body.innerHTML = ` | |
| <div style="text-align:center;padding:50px;"> | |
| <h2 style="color:#ff4444;">Error Loading Image</h2> | |
| <p>HTTP ${response.status}: Could not fetch image</p> | |
| <p><a href="${decodedUrl}" style="color:#4CAF50;">Try original URL</a></p> | |
| <p><a href="javascript:history.back()" style="color:#4CAF50;">Go Back</a></p> | |
| </div> | |
| `; | |
| } | |
| }, | |
| onerror: function() { | |
| document.body.innerHTML = ` | |
| <div style="text-align:center;padding:50px;"> | |
| <h2 style="color:#ff4444;">Network Error</h2> | |
| <p>Could not fetch the image.</p> | |
| <p><a href="${decodedUrl}" style="color:#4CAF50;">Try original URL</a></p> | |
| <p><a href="javascript:history.back()" style="color:#4CAF50;">Go Back</a></p> | |
| </div> | |
| `; | |
| }, | |
| timeout: 30000 | |
| }); | |
| }; | |
| // Wait for document to be available | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', showLoadingAndFetch); | |
| } else { | |
| // Document already loaded | |
| showLoadingAndFetch(); | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment