您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Redirect Medium's premium posts to Freedium, also works for custom domains
// ==UserScript== // @name Medium Unlocker (via Freedium) // @namespace http://tampermonkey.net/ // @version 0.0.4 // @description Redirect Medium's premium posts to Freedium, also works for custom domains // @author d0gkiller87 // @match *://*/* // @icon https://www.google.com/s2/favicons?sz=64&domain=medium.com // @grant none // @run-at document-start // @noframes // @license MIT // ==/UserScript== /* jshint esversion: 11 */ (function() { 'use strict'; function hasMediumLogo() { return document.querySelector( '#wordmark-medium-desc' ) !== null; } function isMediumPost() { const path = window.location.pathname; const pathParts = path.split( '/' ); return ( path !== '/' && ( pathParts.length === 2 || ( pathParts.length === 3 && pathParts[1].startsWith( '@' ) ) ) && hasMediumLogo() ); } function askRedirect() { if ( confirm( 'Visit Freedium?' ) ) { window.location.host = 'freedium.cfd'; } } if ( window.top !== window.self ) { return; } let cancel_state_change_handler = false; const readyStateChangeHandler = document.addEventListener( 'readystatechange', event => { if ( document.readyState !== 'interactive' ) return; document.removeEventListener( 'readystatechange', readyStateChangeHandler ); if ( hasMediumLogo() ) { const hookedReplaceState = patchHistory( 'replaceState' ); Object.defineProperty( history, 'replaceState', { configurable: false, enumerable: true, get() { return hookedReplaceState; }, set( fn ) { // modification blocked } }); window.addEventListener( 'replaceState', askRedirect ); } if ( !isMediumPost() ) return; if ( cancel_state_change_handler ) return; askRedirect(); }); function patchHistory( method ) { const original = window.history[method]; return function() { const result = original.apply( this, arguments ); const event = new Event( method ); event.arguments = arguments; window.dispatchEvent( event ); return result; }; } if ( window.performance ) { const newNavigations = window.performance.getEntriesByType( 'navigation' ); for ( const navigation of newNavigations ) { if ( navigation.type === 'back_forward' ) { cancel_state_change_handler = true; document.removeEventListener( 'readystatechange', readyStateChangeHandler ); return; } } const oldNavigation = window.performance?.navigation?.type; if ( oldNavigation && oldNavigation === window.performance.navigation.TYPE_BACK_FORWARD ) { cancel_state_change_handler = true; document.removeEventListener( 'readystatechange', readyStateChangeHandler ); return; } } })();