Scribd Bypass (domain switch only)

Adds a toolbar button that rewrites Scribd URL to scribd.vdownloaders.com and navigates there.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         Scribd Bypass (domain switch only)
// @description  Adds a toolbar button that rewrites Scribd URL to scribd.vdownloaders.com and navigates there.
// @author       573dave
// @version      2.7
// @license      MIT
// @match        *://*.scribd.com/*
// @grant        GM_addStyle
// @run-at       document-idle
// @noframes
// @namespace https://greasyfork.org/users/1294930
// ==/UserScript==

(function () {
  'use strict';

  // ----- Styles -----
  GM_addStyle(`
    .sb-bar{position:fixed;top:0;left:50%;transform:translateX(-50%);
      display:flex;gap:6px;z-index:2147483646;background:rgba(255,255,255,.92);
      padding:6px 10px;border-radius:0 0 6px 6px;box-shadow:0 2px 6px rgba(0,0,0,.2);
      backdrop-filter:saturate(120%) blur(4px)}
    .sb-btn{font:12px/1.2 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
      padding:6px 10px;background:#FFC017;color:#111;border:none;border-radius:6px;
      cursor:pointer;transition:filter .2s}
    .sb-btn:hover{filter:brightness(.95)}
  `);

  // ----- Helpers -----
  const byId = (id) => document.getElementById(id);
  const create = (tag, props = {}, kids = []) => {
    const el = document.createElement(tag);
    for (const [k, v] of Object.entries(props)) {
      if (k === 'class') el.className = v;
      else if (k === 'text') el.textContent = v;
      else if (k.startsWith('on') && typeof v === 'function') el.addEventListener(k.slice(2), v);
      else el.setAttribute(k, v);
    }
    for (const kid of kids) el.appendChild(kid);
    return el;
  };
  const waitDOM = () =>
    new Promise((r) => (document.readyState === 'loading'
      ? document.addEventListener('DOMContentLoaded', r, { once: true })
      : r()));

  // Build the toolbar if on a document-like page
  function mountBar() {
    if (byId('sb-bar')) return;

    // Only show on typical doc-like routes to avoid cluttering account/home pages
    const path = location.pathname;
    const looksDoc = /(\/(doc|document|presentation|book|read)\/\d+\/?)|(^\/read\/\d+)/i.test(path);
    if (!looksDoc) return;

    const bar = create('div', { id: 'sb-bar', class: 'sb-bar' });
    const dlBtn = create('button', {
      class: 'sb-btn',
      text: 'Download (switch domain)',
      onclick: () => {
        // Rewrite: https://www.scribd.com/<path>  ->  https://scribd.vdownloaders.com/<path>
        // Leave path & query intact; the downloader usually accepts the same structure.
        const u = new URL(location.href);
        u.protocol = 'https:'; // normalize
        u.hostname = 'scribd.vdownloaders.com';
        // Optional: remove marketing params if any (kept minimal)
        // u.searchParams.delete('utm_source'); u.searchParams.delete('utm_medium'); u.searchParams.delete('utm_campaign');

        location.assign(u.toString());
      },
    });

    bar.append(dlBtn);
    document.documentElement.appendChild(bar);
  }

  // Re-run when SPA navigation occurs
  function onURLChange(cb) {
    let last = location.href;
    const fire = () => {
      const now = location.href;
      if (now !== last) { last = now; cb(); }
    };
    const wrap = (prop) => {
      const orig = history[prop];
      return function () {
        const ret = orig.apply(this, arguments);
        fire();
        return ret;
      };
    };
    history.pushState = wrap('pushState');
    history.replaceState = wrap('replaceState');
    window.addEventListener('popstate', fire);
    // Lightweight observer as a fallback for dynamic DOM/router changes
    const mo = new MutationObserver(() => fire());
    mo.observe(document, { subtree: true, childList: true });
  }

  // Init
  (async () => {
    await waitDOM();
    mountBar();
    onURLChange(() => {
      // Remove prior bar if we left a doc page, then (re)mount if needed
      const old = byId('sb-bar'); if (old) old.remove();
      mountBar();
    });
  })();
})();