History Spammer GUI (Universal)

GUI for spamming history with current URL on any site (shows current URL, prompts only for count)

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         History Spammer GUI (Universal)
// @namespace    http://tampermonkey.net/
// @version      1.300000001
// @description  GUI for spamming history with current URL on any site (shows current URL, prompts only for count)
// @author       Iron web10
// @license      MIT
// @match        *://*/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Prevent duplicate UI if script is injected multiple times
    if (window.__iw10_history_spammer_installed) return;
    window.__iw10_history_spammer_installed = true;

    // Create the menu container
    const menuContainer = document.createElement('div');
    Object.assign(menuContainer.style, {
        position: 'fixed',
        top: '10px',
        right: '10px',
        width: '300px',
        backgroundColor: 'rgba(0, 0, 0, 0.85)',
        color: 'white',
        padding: '10px',
        borderRadius: '6px',
        zIndex: '2147483647', // very high z-index to avoid being hidden
        fontFamily: 'Arial, sans-serif',
        boxSizing: 'border-box'
    });

    const title = document.createElement('div');
    title.innerText = 'History Spammer | Iron web10';
    Object.assign(title.style, { fontSize: '14px', margin: '0 0 8px 0', fontWeight: '600' });
    menuContainer.appendChild(title);

    // Show current URL (updates live)
    const urlDisplay = document.createElement('div');
    urlDisplay.innerText = 'URL: ' + window.location.href;
    Object.assign(urlDisplay.style, { fontSize: '12px', wordBreak: 'break-all', margin: '0 0 8px 0' });
    menuContainer.appendChild(urlDisplay);

    // small helper line
    const hint = document.createElement('div');
    hint.innerText = 'Click "Spam History" → enter count';
    hint.style.fontSize = '11px';
    hint.style.opacity = '0.85';
    menuContainer.appendChild(hint);

    // Spam history function — prompts only for count
    function spamHistory() {
        // ensure using the current URL (in case page changed)
        const currentUrl = window.location.href;
        urlDisplay.innerText = 'URL: ' + currentUrl;

        const raw = prompt("How many times do you want this page to show up in your history?");
        if (raw === null) return; // user cancelled
        const num = parseInt(raw, 10);
        if (isNaN(num) || num <= 0) {
            return alert("Invalid number!");
        }

        // Safety: warn for huge numbers to avoid freezing the tab
        const SOFT_LIMIT = 500;
        if (num > SOFT_LIMIT) {
            const ok = confirm(`You asked to push ${num} entries. This may cause the tab to become unresponsive. Continue?`);
            if (!ok) return;
        }

        // push entries into history; keep behavior minimal to avoid breaking anything else
        try {
            for (let i = 1; i <= num; i++) {
                // pushState with a short string for intermediate entries, final entry uses the actual URL
                history.pushState(null, '', i === num ? currentUrl : i.toString());
            }
            alert(`Flooding successful! ${currentUrl} is now in your history ${num} times.`);
        } catch (e) {
            console.error('History push failed:', e);
            alert('Failed to push to history. See console for details.');
        }
    }

    // Create button
    const spamButton = document.createElement('button');
    spamButton.textContent = 'Spam History';
    Object.assign(spamButton.style, {
        width: '100%',
        padding: '8px',
        marginTop: '8px',
        cursor: 'pointer',
        backgroundColor: '#666',
        color: '#fff',
        border: 'none',
        borderRadius: '4px'
    });
    spamButton.onclick = spamHistory;
    menuContainer.appendChild(spamButton);

    // Add a hide/show toggle
    const toggle = document.createElement('button');
    toggle.textContent = 'Hide';
    Object.assign(toggle.style, {
        float: 'right',
        marginTop: '-34px',
        marginRight: '-6px',
        background: 'transparent',
        color: '#fff',
        border: 'none',
        cursor: 'pointer',
        fontSize: '12px'
    });
    let hidden = false;
    toggle.onclick = () => {
        hidden = !hidden;
        if (hidden) {
            // collapse to a small bar
            menuContainer.style.width = '110px';
            urlDisplay.style.display = 'none';
            spamButton.style.display = 'none';
            hint.style.display = 'none';
            toggle.textContent = 'Show';
            title.innerText = 'History Spammer';
        } else {
            menuContainer.style.width = '300px';
            urlDisplay.style.display = '';
            spamButton.style.display = '';
            hint.style.display = '';
            toggle.textContent = 'Hide';
            title.innerText = 'History Spammer | Iron web10';
        }
    };
    menuContainer.appendChild(toggle);

    // Append menu to the page
    document.body.appendChild(menuContainer);

    // Keep the displayed URL updated when SPA frameworks change location (common on many sites)
    const updateUrlDisplay = () => urlDisplay.innerText = 'URL: ' + window.location.href;
    // intercept pushState/replaceState to update the display
    (function() {
        const _push = history.pushState;
        history.pushState = function() {
            const ret = _push.apply(this, arguments);
            updateUrlDisplay();
            return ret;
        };
        const _replace = history.replaceState;
        history.replaceState = function() {
            const ret = _replace.apply(this, arguments);
            updateUrlDisplay();
            return ret;
        };
        window.addEventListener('popstate', updateUrlDisplay);
    })();

    // As a fallback, observe URL changes (some sites change content without touching history API)
    let lastHref = location.href;
    setInterval(() => {
        if (location.href !== lastHref) {
            lastHref = location.href;
            updateUrlDisplay();
        }
    }, 800);

})();