cldisk Thumb → PDF Helper

自动将 cldisk 缩略图 URL (…/thumb/96.png) 转换为对应 PDF 链接 (…/pdf/{hash}.pdf),支持复制与一键打开。

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         cldisk Thumb → PDF Helper
// @namespace    https://greasyfork.org/users/yourname
// @version      1.2
// @description  自动将 cldisk 缩略图 URL (…/thumb/96.png) 转换为对应 PDF 链接 (…/pdf/{hash}.pdf),支持复制与一键打开。
// @author       你(基于 GPT 辅助编写)
// @license      MIT
// @icon         https://s3.cldisk.com/favicon.ico
// @match        https://s3.cldisk.com/*
// @grant        GM_notification
// @grant        GM_setClipboard
// @run-at       document-idle
// ==/UserScript==

(function () {
  'use strict';

  const HOST_FILTER = 's3.cldisk.com';

  function thumbUrlToPdfUrl(rawUrl) {
    if (!rawUrl) return null;
    try {
      const url = new URL(rawUrl, location.href);
      if (HOST_FILTER && url.host !== HOST_FILTER) return null;
      const idx = url.pathname.indexOf('/thumb/');
      if (idx === -1) return null;
      const beforeThumb = url.pathname.slice(0, idx);
      const segments = beforeThumb.split('/').filter(Boolean);
      if (!segments.length) return null;
      const hash = segments[segments.length - 1];
      const prefix = '/' + segments.join('/');
      const pdfPath = `${prefix}/pdf/${hash}.pdf`;
      return `${url.protocol}//${url.host}${pdfPath}`;
    } catch {
      return null;
    }
  }

  function notify(msg) {
    if (typeof GM_notification === 'function') GM_notification({ text: msg, timeout: 2000 });
    else console.log('[cldisk-helper]', msg);
  }

  function handleThumb(url) {
    const pdfUrl = thumbUrlToPdfUrl(url);
    if (pdfUrl) {
      console.log('[cldisk-helper] thumb =>', pdfUrl);
      notify('检测到缩略图,已解析对应 PDF');
    }
  }

  // Hook fetch
  if (window.fetch) {
    const f = window.fetch;
    window.fetch = function (input, init) {
      if (typeof input === 'string') handleThumb(input);
      return f.apply(this, arguments);
    };
  }

  // Hook XHR
  const o = XMLHttpRequest.prototype.open;
  XMLHttpRequest.prototype.open = function (method, url) {
    handleThumb(url);
    return o.apply(this, arguments);
  };

  // 扫描页面元素并添加按钮
  function attachBtn(el, url) {
    const pdf = thumbUrlToPdfUrl(url);
    if (!pdf || el.dataset.clPdf) return;
    const btn = document.createElement('button');
    btn.textContent = '打开 PDF';
    btn.style.marginLeft = '5px';
    btn.onclick = () => window.open(pdf, '_blank');
    el.insertAdjacentElement('afterend', btn);
    el.dataset.clPdf = 1;
  }

  function scan() {
    document.querySelectorAll('img,a').forEach(el => {
      const url = el.src || el.href;
      if (url) attachBtn(el, url);
    });
  }

  scan();
  new MutationObserver(scan).observe(document.body, { childList: true, subtree: true });

})();