您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Embeds PDFs directly in the page instead of downloading, with fallback and cleanup
当前为
- // ==UserScript==
- // @name PDF Viewer Embedder
- // @namespace *
- // @version 1.7
- // @author zinchaiku
- // @description Embeds PDFs directly in the page instead of downloading, with fallback and cleanup
- // @match *://*/*
- // @grant none
- // @license MIT
- // ==/UserScript==
- (function () {
- 'use strict';
- let currentBlobUrl = null;
- function showPDF(srcUrl, isBlob = false) {
- const existing = document.getElementById('tampermonkey-pdf-viewer');
- if (existing) existing.remove();
- const overlay = document.createElement('div');
- overlay.id = 'tampermonkey-pdf-viewer';
- overlay.style.position = 'fixed';
- overlay.style.top = 0;
- overlay.style.left = 0;
- overlay.style.width = '100vw';
- overlay.style.height = '100vh';
- overlay.style.background = 'rgba(0,0,0,0.8)';
- overlay.style.zIndex = 99999;
- overlay.style.display = 'flex';
- overlay.style.alignItems = 'center';
- overlay.style.justifyContent = 'center';
- const iframe = document.createElement('iframe');
- iframe.src = srcUrl;
- iframe.style.width = '80vw';
- iframe.style.height = '90vh';
- iframe.style.border = 'none';
- iframe.style.background = '#fff';
- overlay.appendChild(iframe);
- // Fallback if iframe fails to load (e.g. X-Frame-Options)
- iframe.onerror = () => {
- overlay.remove();
- if (isBlob && currentBlobUrl) {
- URL.revokeObjectURL(currentBlobUrl);
- currentBlobUrl = null;
- }
- window.open(srcUrl, '_blank');
- };
- // Close button
- const closeBtn = document.createElement('button');
- closeBtn.textContent = 'Close PDF';
- closeBtn.style.position = 'absolute';
- closeBtn.style.top = '20px';
- closeBtn.style.right = '200px';
- closeBtn.style.zIndex = 100000;
- closeBtn.style.padding = '2px 6px';
- closeBtn.style.fontSize = '1.2em';
- closeBtn.onclick = () => {
- overlay.remove();
- if (isBlob && currentBlobUrl) {
- URL.revokeObjectURL(currentBlobUrl);
- currentBlobUrl = null;
- }
- };
- overlay.appendChild(closeBtn);
- // "Open in New Tab" button
- const newTabBtn = document.createElement('button');
- newTabBtn.textContent = 'Open in New Tab';
- newTabBtn.style.position = 'absolute';
- newTabBtn.style.top = '20px';
- newTabBtn.style.right = '40px';
- newTabBtn.style.zIndex = 100000;
- newTabBtn.style.padding = '2px 6px';
- newTabBtn.style.fontSize = '1.2em';
- newTabBtn.onclick = () => {
- window.open(srcUrl, '_blank');
- };
- overlay.appendChild(newTabBtn);
- document.body.appendChild(overlay);
- // Track for cleanup
- if (isBlob) {
- currentBlobUrl = srcUrl;
- } else {
- currentBlobUrl = null;
- }
- }
- function isPDFLink(href) {
- try {
- const url = new URL(href, window.location.href);
- return url.pathname.toLowerCase().endsWith('.pdf');
- } catch {
- return false;
- }
- }
- function attachPDFInterceptors() {
- document.querySelectorAll('a[href]').forEach(link => {
- const href = link.getAttribute('href');
- if (!href || link.dataset.tmPdfBound) return;
- const isWrapper = href.includes('_download.html');
- const isDirectPDF = isPDFLink(href);
- if (isWrapper || isDirectPDF) {
- link.dataset.tmPdfBound = "1";
- link.addEventListener('click', function (e) {
- e.preventDefault();
- if (isDirectPDF) {
- showPDF(link.href);
- } else {
- fetch(link.href, { credentials: 'include' })
- .then(res => {
- const contentType = res.headers.get('Content-Type') || '';
- if (contentType.includes('pdf')) {
- return res.blob().then(blob => {
- const blobUrl = URL.createObjectURL(blob);
- showPDF(blobUrl, true);
- });
- } else {
- window.location.href = link.href;
- }
- })
- .catch(err => {
- alert("Could not open PDF: " + err);
- window.location.href = link.href;
- });
- }
- });
- }
- });
- }
- window.addEventListener('keydown', (e) => {
- if (e.key === 'Escape') {
- const viewer = document.getElementById('tampermonkey-pdf-viewer');
- if (viewer) {
- viewer.remove();
- if (currentBlobUrl) {
- URL.revokeObjectURL(currentBlobUrl);
- currentBlobUrl = null;
- }
- }
- }
- });
- attachPDFInterceptors();
- const observer = new MutationObserver(attachPDFInterceptors);
- observer.observe(document.body, { childList: true, subtree: true });
- })();