// ==UserScript== // @name Scribd Downloader // @namespace https://github.com/ThanhNguyxn/scribd-downloader // @version 2.1.0 // @description ๐Ÿ“š Download documents from Scribd for free as PDF - Fully automated! // @author ThanhNguyxn // @match https://www.scribd.com/* // @icon https://www.scribd.com/favicon.ico // @grant GM_addStyle // @grant GM_setClipboard // @grant GM_openInTab // @run-at document-idle // @license MIT // @homepageURL https://github.com/ThanhNguyxn/scribd-downloader // @supportURL https://github.com/ThanhNguyxn/scribd-downloader/issues // @downloadURL https://raw.githubusercontent.com/ThanhNguyxn/scribd-downloader/main/userscript.js // @updateURL https://raw.githubusercontent.com/ThanhNguyxn/scribd-downloader/main/userscript.js // ==/UserScript== (function() { 'use strict'; // ==================== CONFIG ==================== const BUTTON_DELAY = 1500; const GITHUB_URL = 'https://github.com/ThanhNguyxn/scribd-downloader'; const DONATE_URL = 'https://buymeacoffee.com/thanhnguyxn'; // ==================== STYLES ==================== const styles = ` /* Main floating button - TOP RIGHT */ #sd-floating-btn { position: fixed !important; top: 80px !important; right: 20px !important; z-index: 2147483647 !important; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; color: white !important; border: none !important; padding: 12px 20px !important; border-radius: 12px !important; font-size: 14px !important; font-weight: 700 !important; cursor: pointer !important; box-shadow: 0 4px 15px rgba(102, 126, 234, 0.5) !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; display: flex !important; align-items: center !important; gap: 8px !important; transition: all 0.3s ease !important; text-decoration: none !important; } #sd-floating-btn:hover { transform: scale(1.05) !important; box-shadow: 0 6px 25px rgba(102, 126, 234, 0.6) !important; } #sd-floating-btn:active { transform: scale(0.98) !important; } #sd-floating-btn.loading { background: linear-gradient(135deg, #ffa726 0%, #fb8c00 100%) !important; pointer-events: none !important; } #sd-popup { position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; background: rgba(0,0,0,0.85) !important; z-index: 2147483647 !important; display: flex !important; justify-content: center !important; align-items: center !important; opacity: 0; visibility: hidden; transition: all 0.3s ease !important; } #sd-popup.show { opacity: 1 !important; visibility: visible !important; } #sd-popup-content { background: white !important; padding: 30px !important; border-radius: 20px !important; max-width: 420px !important; width: 90% !important; text-align: center !important; box-shadow: 0 25px 80px rgba(0,0,0,0.4) !important; transform: scale(0.9); transition: transform 0.3s ease !important; } #sd-popup.show #sd-popup-content { transform: scale(1) !important; } #sd-popup h2 { margin: 0 0 20px 0 !important; color: #333 !important; font-size: 22px !important; font-weight: 700 !important; } #sd-url-display { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%) !important; color: #00d9ff !important; padding: 15px !important; border-radius: 10px !important; font-family: 'Monaco', 'Consolas', monospace !important; font-size: 12px !important; word-break: break-all !important; margin: 15px 0 !important; text-align: left !important; border: 2px solid #667eea !important; user-select: all !important; cursor: text !important; } .sd-btn { padding: 12px 24px !important; border: none !important; border-radius: 10px !important; font-size: 14px !important; font-weight: 600 !important; cursor: pointer !important; transition: all 0.2s ease !important; margin: 5px !important; text-decoration: none !important; display: inline-flex !important; align-items: center !important; gap: 6px !important; } .sd-btn-primary { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; color: white !important; } .sd-btn-success { background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%) !important; color: white !important; } .sd-btn-warning { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%) !important; color: white !important; } .sd-btn-close { background: #e0e0e0 !important; color: #333 !important; } .sd-btn:hover { transform: scale(1.05) !important; box-shadow: 0 5px 20px rgba(0,0,0,0.2) !important; } .sd-info { background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%) !important; border-left: 4px solid #4caf50 !important; padding: 12px 15px !important; margin: 15px 0 !important; border-radius: 0 10px 10px 0 !important; text-align: left !important; font-size: 13px !important; color: #2e7d32 !important; } .sd-btn-group { display: flex !important; gap: 8px !important; justify-content: center !important; flex-wrap: wrap !important; margin-top: 15px !important; } .sd-links { margin-top: 20px !important; padding-top: 15px !important; border-top: 1px solid #eee !important; display: flex !important; justify-content: center !important; gap: 15px !important; } .sd-link { color: #666 !important; text-decoration: none !important; font-size: 12px !important; display: flex !important; align-items: center !important; gap: 5px !important; transition: color 0.2s !important; } .sd-link:hover { color: #667eea !important; } /* Progress bar in button */ .sd-progress-inline { width: 100px !important; height: 6px !important; background: rgba(255,255,255,0.3) !important; border-radius: 3px !important; overflow: hidden !important; margin-left: 8px !important; } .sd-progress-inline-fill { height: 100% !important; background: white !important; width: 0% !important; transition: width 0.3s ease !important; border-radius: 3px !important; } /* For embed page - TOP RIGHT green button */ #sd-download-btn { position: fixed !important; top: 20px !important; right: 20px !important; z-index: 2147483647 !important; background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%) !important; color: white !important; border: none !important; padding: 14px 24px !important; border-radius: 12px !important; font-size: 15px !important; font-weight: 700 !important; cursor: pointer !important; box-shadow: 0 4px 15px rgba(17, 153, 142, 0.5) !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; display: flex !important; align-items: center !important; gap: 8px !important; transition: all 0.3s ease !important; } #sd-download-btn:hover { transform: scale(1.05) !important; box-shadow: 0 6px 25px rgba(17, 153, 142, 0.6) !important; } #sd-download-btn.loading { background: linear-gradient(135deg, #ffa726 0%, #fb8c00 100%) !important; } #sd-progress-popup { position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; background: rgba(0,0,0,0.9) !important; z-index: 2147483647 !important; display: flex !important; justify-content: center !important; align-items: center !important; } #sd-progress-content { background: white !important; padding: 35px !important; border-radius: 20px !important; text-align: center !important; min-width: 320px !important; } #sd-progress-bar { width: 100% !important; height: 10px !important; background: #e0e0e0 !important; border-radius: 10px !important; overflow: hidden !important; margin: 20px 0 !important; } #sd-progress-fill { height: 100% !important; background: linear-gradient(90deg, #667eea, #764ba2) !important; width: 0% !important; transition: width 0.3s ease !important; border-radius: 10px !important; } #sd-progress-text { color: #666 !important; font-size: 15px !important; margin-bottom: 10px !important; } `; // Inject styles const styleEl = document.createElement('style'); styleEl.textContent = styles; document.head.appendChild(styleEl); // ==================== UTILITIES ==================== function getDocId() { const url = window.location.href; const match = url.match(/(?:document|doc|embeds|read)\/(\d+)/); return match ? match[1] : null; } function isEmbed() { return window.location.href.includes('/embeds/'); } function getEmbedUrl(id) { return `https://www.scribd.com/embeds/${id}/content`; } function copyText(text) { try { if (typeof GM_setClipboard === 'function') { GM_setClipboard(text, 'text'); return true; } } catch(e) {} try { navigator.clipboard.writeText(text); return true; } catch(e) {} try { const ta = document.createElement('textarea'); ta.value = text; ta.style.cssText = 'position:fixed;top:-9999px;left:-9999px'; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); ta.remove(); return true; } catch(e) {} return false; } function sleep(ms) { return new Promise(r => setTimeout(r, ms)); } // ==================== MAIN PAGE FUNCTIONS ==================== function showMainButton() { if (document.getElementById('sd-floating-btn')) return; const docId = getDocId(); if (!docId) return; const btn = document.createElement('button'); btn.id = 'sd-floating-btn'; btn.innerHTML = '๐Ÿ“ฅ Download PDF'; btn.onclick = startAutoDownload; document.body.appendChild(btn); } async function startAutoDownload() { const btn = document.getElementById('sd-floating-btn'); const docId = getDocId(); if (!docId) { alert('Cannot find document ID!'); return; } const embedUrl = getEmbedUrl(docId); // Change button to loading state btn.classList.add('loading'); btn.innerHTML = 'โณ Opening...'; // Show quick popup then auto-open showAutoPopup(embedUrl); } function showAutoPopup(embedUrl) { const existing = document.getElementById('sd-popup'); if (existing) existing.remove(); const popup = document.createElement('div'); popup.id = 'sd-popup'; popup.innerHTML = `

๐Ÿ“š Scribd Downloader

โœจ Auto mode: Opening embed page in new tab...
${embedUrl}

A new tab will open automatically.
Click the green button there to download!

`; document.body.appendChild(popup); requestAnimationFrame(() => { popup.classList.add('show'); }); // Auto open after 1 second const autoTimer = setTimeout(() => { openEmbedPage(embedUrl); }, 1500); // Event handlers document.getElementById('sd-open-now').onclick = function() { clearTimeout(autoTimer); openEmbedPage(embedUrl); }; document.getElementById('sd-open-incognito').onclick = function() { clearTimeout(autoTimer); copyText(embedUrl); this.innerHTML = 'โœ… URL Copied!'; showManualInstructions(); }; document.getElementById('sd-close-btn').onclick = function() { clearTimeout(autoTimer); closePopup(); }; popup.onclick = function(e) { if (e.target === popup) { clearTimeout(autoTimer); closePopup(); } }; } function openEmbedPage(url) { // Open in new tab if (typeof GM_openInTab === 'function') { GM_openInTab(url, { active: true }); } else { window.open(url, '_blank'); } // Update button const btn = document.getElementById('sd-floating-btn'); if (btn) { btn.classList.remove('loading'); btn.innerHTML = 'โœ… Opened!'; setTimeout(() => { btn.innerHTML = '๐Ÿ“ฅ Download PDF'; }, 3000); } // Close popup after small delay setTimeout(closePopup, 500); } function showManualInstructions() { const content = document.getElementById('sd-popup-content'); if (!content) return; content.innerHTML = `

๐Ÿ•ต๏ธ Manual Mode

โœ… URL copied! Follow these steps:
  1. Press Ctrl+Shift+N (Incognito window)
  2. Paste the URL (Ctrl+V)
  3. Press Enter
  4. Click the green Download button
`; document.getElementById('sd-close-btn2').onclick = closePopup; } function closePopup() { const popup = document.getElementById('sd-popup'); const btn = document.getElementById('sd-floating-btn'); if (popup) { popup.classList.remove('show'); setTimeout(() => popup.remove(), 300); } if (btn) { btn.classList.remove('loading'); btn.innerHTML = '๐Ÿ“ฅ Download PDF'; } } // ==================== EMBED PAGE FUNCTIONS ==================== function showEmbedButton() { if (document.getElementById('sd-download-btn')) return; const btn = document.createElement('button'); btn.id = 'sd-download-btn'; btn.innerHTML = 'โฌ‡๏ธ Download PDF'; btn.onclick = startDownload; document.body.appendChild(btn); // Auto-start download after 2 seconds if opened from main script if (document.referrer.includes('scribd.com')) { setTimeout(() => { const autoBtn = document.getElementById('sd-download-btn'); if (autoBtn && !autoBtn.classList.contains('loading')) { // Show notification autoBtn.innerHTML = '๐Ÿš€ Starting...'; setTimeout(startDownload, 500); } }, 2000); } } async function startDownload() { const btn = document.getElementById('sd-download-btn'); btn.classList.add('loading'); btn.innerHTML = 'โณ Processing...'; // Create progress popup const progress = document.createElement('div'); progress.id = 'sd-progress-popup'; progress.innerHTML = `

๐Ÿ“š Preparing PDF...

Loading pages...

Please wait, this may take a moment...

`; document.body.appendChild(progress); const fill = document.getElementById('sd-progress-fill'); const text = document.getElementById('sd-progress-text'); try { // Step 1: Scroll all pages text.textContent = '๐Ÿ“„ Loading all pages...'; const pages = document.querySelectorAll("[class*='page']"); if (pages.length > 0) { for (let i = 0; i < pages.length; i++) { pages[i].scrollIntoView({ behavior: 'auto', block: 'center' }); await sleep(350); const pct = Math.round(((i + 1) / pages.length) * 50); fill.style.width = pct + '%'; text.textContent = `๐Ÿ“„ Loading page ${i + 1}/${pages.length}...`; } } else { // Fallback scroll const h = document.documentElement.scrollHeight; for (let i = 0; i <= 20; i++) { window.scrollTo(0, (h / 20) * i); await sleep(150); fill.style.width = (i * 2.5) + '%'; } } // Step 2: Remove junk fill.style.width = '60%'; text.textContent = '๐Ÿงน Cleaning up...'; await sleep(200); const junk = [ '.toolbar_top', '.toolbar_bottom', '.promo_div', '[class*="blur"]', '[class*="paywall"]', '[class*="overlay"]', '[class*="upsell"]', '[class*="signup"]', '.ReactModalPortal', '[class*="banner"]', '[class*="modal"]' ]; junk.forEach(sel => { try { document.querySelectorAll(sel).forEach(el => el.remove()); } catch(e) {} }); // Step 3: Fix visibility fill.style.width = '80%'; text.textContent = 'โœจ Optimizing...'; await sleep(200); document.querySelectorAll('*').forEach(el => { try { const s = getComputedStyle(el); if (s.filter?.includes('blur')) el.style.filter = 'none'; if (parseFloat(s.opacity) < 1) el.style.opacity = '1'; } catch(e) {} }); // Scroll to top window.scrollTo(0, 0); // Step 4: Print fill.style.width = '100%'; text.textContent = 'โœ… Ready! Opening print dialog...'; await sleep(400); progress.remove(); window.print(); // Reset button btn.classList.remove('loading'); btn.innerHTML = 'โœ… Done! Print again?'; setTimeout(() => { btn.innerHTML = 'โฌ‡๏ธ Download PDF'; }, 5000); } catch (err) { console.error('Download error:', err); progress.remove(); btn.classList.remove('loading'); btn.innerHTML = 'โŒ Error - Try again'; setTimeout(() => { btn.innerHTML = 'โฌ‡๏ธ Download PDF'; }, 3000); } } // ==================== INIT ==================== function init() { // Check if we're on Scribd if (!window.location.hostname.includes('scribd.com')) return; setTimeout(() => { if (isEmbed()) { showEmbedButton(); } else if (getDocId()) { showMainButton(); } }, BUTTON_DELAY); } // Run if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();