Disable AMP Pages

Automatically redirects AMP pages to their original canonical links, and strips AMP hijacking from Google Search and News

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Disable AMP Pages
// @namespace    RGlzYWJsZSBBTVAgUGFnZXM
// @version      1.0
// @description  Automatically redirects AMP pages to their original canonical links, and strips AMP hijacking from Google Search and News
// @author       smed79
// @license      GPLv3
// @icon         https://i25.servimg.com/u/f25/11/94/21/24/amp10.png
// @match        *://*/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const host = window.location.hostname;
    const href = window.location.href;

    // Helper: Safely extract Canonical URL
    const getCanonicalUrl = () => {
        const link = document.querySelector('link[rel="canonical"]');
        if (!link || !link.href) return null;
        try {
            const url = new URL(link.href);
            // Remove lingering amp query parameters
            if (url.searchParams.has("amp")) url.searchParams.delete("amp");
            return url.href;
        } catch (e) {
            return null;
        }
    };

    // --- 1. Clean Google Search & News Links ---
    const cleanGoogleLinks = () => {
        if (!host.includes('google.')) return;

        // Clean Google Search results (Removes AMP hijacking and tracking)
        const hijackAttrs = ['ping', 'data-ved', 'data-amp-cur', 'data-amp-title', 'data-amp', 'data-amp-vgi', 'jsaction', 'data-amp-cdn'];
        
        document.querySelectorAll('a[data-amp], a[data-amp-cdn], a[data-ved]:has(span + svg)').forEach(a => {
            hijackAttrs.forEach(attr => a.removeAttribute(attr));
            
            // Fix hardcoded AMP CDN URLs
            if (a.href.includes('cdn.ampproject.org/')) {
                const match = a.href.match(/cdn\.ampproject\.org\/(?:v|wp|c)\/s\/(.+)/);
                if (match && match[1]) {
                    a.href = 'https://' + decodeURIComponent(match[1]).split('?')[0];
                }
            }
            
            // Hide the AMP logo icon next to the link
            const icon = a.querySelector('[aria-label="AMP logo"], [aria-label="Logo AMP"]');
            if (icon) icon.style.display = 'none';
        });

        // Clean Google News (Decodes base64 jslog to find the real URL)
        if (host.includes('news.google.')) {
            document.querySelectorAll('a[jslog]:not([data-cleaned])').forEach(a => {
                const jslog = a.getAttribute('jslog');
                if (!jslog) return;
                
                try {
                    const b64 = jslog.substring(jslog.indexOf(":") + 1, jslog.indexOf(";"));
                    const decodedStr = atob(b64);
                    // Match any valid http/https URL inside the decoded payload
                    const urlMatch = decodedStr.match(/(https?:\/\/[^"'\s\]]+)/g);
                    
                    if (urlMatch) {
                        const realUrl = urlMatch.find(url => !url.includes('amp') && !url.includes('google.com'));
                        if (realUrl) {
                            a.href = realUrl;
                            a.dataset.cleaned = "true"; // Prevent processing twice
                            
                            // Force native click to bypass Google's JS listeners
                            a.addEventListener('click', (e) => {
                                e.preventDefault();
                                e.stopImmediatePropagation();
                                window.location.href = realUrl;
                            }, true);
                        }
                    }
                } catch (e) {}
            });
        }
    };

    // --- 2. Redirect standard AMP pages ---
    const checkAMPPage = () => {
        // Detects standard AMP properties natively rather than guessing URLs
        const isAMP = (document.documentElement && (
                      document.documentElement.hasAttribute('amp') || 
                      document.documentElement.hasAttribute('⚡'))) || 
                      document.querySelector('script[src*="cdn.ampproject.org"]');
        
        if (isAMP) {
            const canonical = getCanonicalUrl();
            if (canonical && canonical !== window.location.href) {
                window.location.replace(canonical);
                return true; // Indicates we are redirecting
            }
        }
        return false;
    };

    // --- 3. Redirect Yandex Turbo Pages ---
    const checkYandexTurbo = () => {
        if ((host.includes('yandex.ru') && href.includes('/turbo')) || host.includes('turbopages.org')) {
            const canonical = getCanonicalUrl();
            if (canonical) {
                window.location.replace(canonical);
                return true;
            }
        }
        return false;
    };

    // --- Execution ---
    const observer = new MutationObserver(() => {
        // 1. Run Google Checks First
        cleanGoogleLinks();

        // 2. Check standard AMP site redirects (If redirecting, stop processing)
        if (checkAMPPage()) return;

        // 3. Check Yandex Turbo
        checkYandexTurbo();
    });

    // Safely attach observer as early as possible
    if (document.documentElement) {
        observer.observe(document.documentElement, { childList: true, subtree: true });
    } else {
        const initObserver = new MutationObserver((mutations, me) => {
            if (document.documentElement) {
                observer.observe(document.documentElement, { childList: true, subtree: true });
                me.disconnect();
            }
        });
        initObserver.observe(document, { childList: true, subtree: true });
    }

})();