🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

Greasy Fork is available in English.

📂 缓存分发状态(共享加速已生效)
🕒 页面同步时间:2025/12/25 08:55:38
🔄 下次更新时间:2025/12/25 09:55:38
手动刷新缓存

Path Notes

Add and save notes for different website paths

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

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

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

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

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name         Path Notes
// @namespace    Violentmonkey Scripts
// @version      2.0
// @description  Add and save notes for different website paths
// @author       maanimis
// @match        *://*/*
// @grant        GM_registerMenuCommand
// @run-at       document-end
// @license MIT
// ==/UserScript==

(function() {
    'use strict';
    
    // Configuration
    const CONFIG = {
        notesPanelClass: 'path-notes-container',
        overlayClass: 'path-notes-overlay',
        textareaClass: 'path-notes-textarea',
        toggleBtnClass: 'path-notes-toggle',
        storageKey: 'pathNotes',
        animationDuration: 300, // ms
        debounceInterval: 500, // ms for autosave debounce
    };
    
    // DOM Elements (initialized later)
    let elements = {
        container: null,
        overlay: null,
        textarea: null,
        toggleBtn: null
    };
    
    // State management
    const state = {
        isVisible: false,
        currentPath: window.location.pathname + window.location.search,
        notes: {},
        saveTimeout: null
    };
    
    // Styles
    const styles = `
        .${CONFIG.overlayClass} {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            backdrop-filter: blur(3px);
            z-index: 9999;
            opacity: 0;
            visibility: hidden;
            transition: opacity ${CONFIG.animationDuration}ms ease;
        }
        
        .${CONFIG.notesPanelClass} {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%) scale(0.95);
            background-color: #ffffff;
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
            border-radius: 12px;
            padding: 20px;
            z-index: 10000;
            max-width: 500px;
            width: 90%;
            display: flex;
            flex-direction: column;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            opacity: 0;
            visibility: hidden;
            transition: opacity ${CONFIG.animationDuration}ms ease, 
                        transform ${CONFIG.animationDuration}ms ease;
        }
        
        .${CONFIG.notesPanelClass}.visible {
            opacity: 1;
            visibility: visible;
            transform: translate(-50%, -50%) scale(1);
        }
        
        .${CONFIG.overlayClass}.visible {
            opacity: 1;
            visibility: visible;
        }
        
        .path-notes-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            border-bottom: 1px solid #eee;
            padding-bottom: 10px;
        }
        
        .path-notes-title {
            margin: 0;
            color: #333;
            font-size: 18px;
            font-weight: 600;
        }
        
        .path-notes-content {
            display: flex;
            flex-direction: column;
            flex-grow: 1;
        }
        
        .path-notes-path {
            font-size: 14px;
            color: #666;
            margin-bottom: 10px;
            word-break: break-all;
        }
        
        .${CONFIG.textareaClass} {
            width: 100%;
            min-height: 180px;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 8px;
            resize: vertical;
            font-family: inherit;
            font-size: 14px;
            line-height: 1.5;
            color: #333;
            transition: border-color 0.2s;
        }
        
        .${CONFIG.textareaClass}:focus {
            outline: none;
            border-color: #4d90fe;
            box-shadow: 0 0 0 2px rgba(77, 144, 254, 0.2);
        }
        
        .${CONFIG.toggleBtnClass} {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 50px;
            height: 50px;
            border-radius: 50%;
            background-color: #4d90fe;
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 24px;
            cursor: pointer;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
            z-index: 9999;
            transition: background-color 0.2s, transform 0.2s;
        }
        
        .${CONFIG.toggleBtnClass}:hover {
            background-color: #3a7be0;
            transform: scale(1.05);
        }
        
        @media (max-width: 600px) {
            .${CONFIG.notesPanelClass} {
                width: 85%;
                max-width: none;
            }
            
            .${CONFIG.textareaClass} {
                min-height: 140px;
            }
        }
    `;
    
    // Load notes from localStorage
    function loadNotes() {
        try {
            state.notes = JSON.parse(localStorage.getItem(CONFIG.storageKey)) || {};
        } catch (e) {
            state.notes = {};
        }
        return state.notes;
    }
    
    // Save notes to localStorage
    function saveNotes() {
        localStorage.setItem(CONFIG.storageKey, JSON.stringify(state.notes));
    }
    
    // Save current note with debounce
    function saveCurrentNote(text) {
        clearTimeout(state.saveTimeout);
        state.saveTimeout = setTimeout(() => {
            state.notes[state.currentPath] = text;
            saveNotes();
        }, CONFIG.debounceInterval);
    }
    
    // Show/hide the notes panel
    function toggleNotesPanel() {
        state.isVisible = !state.isVisible;
        
        if (state.isVisible) {
            elements.container.classList.add('visible');
            elements.overlay.classList.add('visible');
            elements.textarea.focus();
        } else {
            elements.container.classList.remove('visible');
            elements.overlay.classList.remove('visible');
        }
    }
    
    // Create UI elements
    function createUI() {
        // Add styles
        const styleElement = document.createElement('style');
        styleElement.textContent = styles;
        document.head.appendChild(styleElement);
        
        // Create overlay for background blur
        const overlay = document.createElement('div');
        overlay.className = CONFIG.overlayClass;
        document.body.appendChild(overlay);
        
        // Create notes container
        const container = document.createElement('div');
        container.className = CONFIG.notesPanelClass;
        
        // Load stored notes
        loadNotes();
        const currentNote = state.notes[state.currentPath] || '';
        
        // Create notes UI
        container.innerHTML = `
            <div class="path-notes-header">
                <h3 class="path-notes-title">Path Notes</h3>
            </div>
            <div class="path-notes-content">
                <div class="path-notes-path">Current path: ${state.currentPath}</div>
                <textarea class="${CONFIG.textareaClass}" placeholder="Add your notes for this page...">${currentNote}</textarea>
            </div>
        `;
        
        document.body.appendChild(container);
        
        // Create toggle button
        const toggleButton = document.createElement('div');
        toggleButton.className = CONFIG.toggleBtnClass;
        toggleButton.innerHTML = '📝';
        toggleButton.title = 'Toggle Path Notes';
        document.body.appendChild(toggleButton);
        
        // Store elements references
        elements.container = container;
        elements.overlay = overlay;
        elements.textarea = container.querySelector(`.${CONFIG.textareaClass}`);
        elements.toggleBtn = toggleButton;
        
        // Setup event listeners
        setupEventListeners();
    }
    
    // Setup event listeners
    function setupEventListeners() {
        // Toggle button click
        elements.toggleBtn.addEventListener('click', toggleNotesPanel);
        
        // Clicking overlay closes panel
        elements.overlay.addEventListener('click', () => {
            if (state.isVisible) {
                toggleNotesPanel();
            }
        });
        
        // Auto-save on typing
        elements.textarea.addEventListener('input', (e) => {
            saveCurrentNote(e.target.value);
        });
    }
    
    // Register menu command
    function registerMenuCommand() {
        if (typeof GM_registerMenuCommand !== 'undefined') {
            GM_registerMenuCommand('Open Path Notes', toggleNotesPanel);
        }
    }
    
    // Initialize the userscript
    function initialize() {
        createUI();
        registerMenuCommand();
    }
    
    // Start when the page is fully loaded
    window.addEventListener('load', initialize);
})();