您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds alternate reading links (ReadMedium and Freedium) to Medium paywalled articles.
当前为
// ==UserScript== // @name Medium Unlocked // @namespace https://github.com/ShrekBytes // @version 1.3 // @description Adds alternate reading links (ReadMedium and Freedium) to Medium paywalled articles. // @author ShrekBytes // @license MIT // @match https://medium.com/* // @match https://*.medium.com/* // @match https://infosecwriteups.com/* // @match https://*.infosecwriteups.com/* // @icon https://raw.githubusercontent.com/ShrekBytes/medium-unlocked/refs/heads/main/freedom.png // @grant none // @noframes // @homepageURL https://github.com/ShrekBytes/medium-unlocked // @supportURL https://github.com/ShrekBytes/medium-unlocked/issues // ==/UserScript== (function () { 'use strict'; let buttonsAdded = false; let checkTimeout; // Utility: Debounce function function debounce(fn, delay) { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), delay); }; } // Check if the article is member-only (paywalled) function isMemberOnlyArticle() { const quickSelectors = [ '[data-testid="paywall"]', '[data-testid="meter-stats"]', '[data-testid="subscribe-paywall"]' ]; for (let selector of quickSelectors) { if (document.querySelector(selector)) { return true; } } const bodyText = document.body.textContent; return bodyText.includes('Member-only story') || bodyText.includes('Subscribe to read') || bodyText.includes('Become a member'); } // Create styled link button function createButton(text, url, topPosition) { const button = document.createElement('a'); button.innerHTML = text; button.href = url; button.target = '_blank'; button.rel = 'noopener noreferrer'; button.className = 'medium-reader-btn'; button.style.cssText = ` position: absolute; top: ${topPosition}px; right: 64px; z-index: 9999; background: rgba(255, 255, 255, 0.44); backdrop-filter: blur(2px); color: black; border: 1px solid black; border-radius: 2px; font-size: 14px; font-weight: 400; cursor: pointer; width: 100px; height: 36px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; text-decoration: none; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; `; return button; } // Add external links if not already present function addButtons() { if (buttonsAdded) return; // Remove any existing buttons (in case of navigation) document.querySelectorAll('.medium-reader-btn').forEach(btn => btn.remove()); const currentUrl = window.location.href; const encodedUrl = encodeURIComponent(currentUrl); const readMediumBtn = createButton('ReadMedium', `https://readmedium.com/en/${encodedUrl}`, 400); const freediumBtn = createButton('Freedium', `https://freedium.cfd/${encodedUrl}`, 440); document.body.appendChild(readMediumBtn); document.body.appendChild(freediumBtn); buttonsAdded = true; } // Debounced paywall check const checkForPaywall = debounce(() => { if (isMemberOnlyArticle() && !buttonsAdded) { addButtons(); } }, 500); // Initialize on page load function init() { buttonsAdded = false; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', checkForPaywall); } else { checkForPaywall(); } } // Track URL changes for SPA behavior let currentUrl = window.location.href; const observer = new MutationObserver(() => { if (window.location.href !== currentUrl) { currentUrl = window.location.href; buttonsAdded = false; checkForPaywall(); } }); observer.observe(document.body, { childList: true, subtree: true // ← More reliable in SPA }); // Also respond to back/forward navigation window.addEventListener('popstate', () => { buttonsAdded = false; checkForPaywall(); }); // Kick off init(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址