Cookie Manager GUI

Advanced GUI cookie viewer and manager for current domain

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

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

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

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

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         Cookie Manager GUI
// @namespace    gl4_manu
// @version      1.0.0
// @description  Advanced GUI cookie viewer and manager for current domain
// @author       gl4_manu
// @match        *://*/*
// @grant        GM_setClipboard
// @grant        GM_deleteCookie
// @grant        GM_setCookie
// @grant        GM_listValues
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

(function () {
    'use strict';

    class CookieGUI {
        constructor() {
            this.cookies = {};
            this.isDragging = false;
            this.dragOffset = { x: 0, y: 0 };
            this.currentSort = 'name';
            this.sortDirection = 'asc';
            this.createUI();
            this.loadCookies();
            this.setupKeyboardShortcuts();
        }

        parseCookies() {
            return document.cookie
                .split(';')
                .map(cookie => cookie.trim())
                .filter(Boolean)
                .reduce((acc, cookie) => {
                    const [name, ...rest] = cookie.split('=');
                    const decodedName = decodeURIComponent(name);
                    const decodedValue = decodeURIComponent(rest.join('='));

                    acc[decodedName] = {
                        value: decodedValue,
                        length: decodedValue.length,
                        hasSpecialChars: /[^a-zA-Z0-9\s]/.test(decodedValue)
                    };

                    return acc;
                }, {});
        }

        loadCookies() {
            this.cookies = this.parseCookies();
            this.updateStats();
            this.renderCookies();
        }

        updateStats() {
            const stats = document.getElementById('tm-stats');
            if (stats) {
                const totalCookies = Object.keys(this.cookies).length;
                const totalSize = Object.values(this.cookies).reduce((sum, cookie) => sum + cookie.length, 0);
                stats.innerHTML = `📊 ${totalCookies} cookies | ${(totalSize / 1024).toFixed(1)} KB`;
            }
        }

        createUI() {
            this.container = document.createElement('div');
            this.container.id = 'tm-cookie-panel';
            this.container.innerHTML = `
                <div class="tm-header" id="tm-drag-handle">
                    <div class="tm-title">
                        <span>🍪 Cookie Manager</span>
                        <span class="tm-badge">v1.0</span>
                    </div>
                    <div class="tm-header-actions">
                        <button id="tm-minimize" class="tm-icon-btn" title="Minimize">−</button>
                        <button id="tm-close" class="tm-icon-btn" title="Close">×</button>
                    </div>
                </div>

                <div class="tm-content">
                    <div class="tm-stats-bar">
                        <span id="tm-stats">Loading...</span>
                        <button id="tm-clear-filter" class="tm-icon-btn-small" title="Clear filter">✕</button>
                    </div>

                    <div class="tm-controls">
                        <div class="tm-control-group">
                            <button id="tm-refresh" class="tm-btn tm-btn-primary" title="Refresh cookies">
                                🔄 Refresh
                            </button>
                            <button id="tm-copy" class="tm-btn tm-btn-secondary" title="Copy as JSON">
                                📋 Copy
                            </button>
                            <button id="tm-export" class="tm-btn tm-btn-secondary" title="Export to file">
                                💾 Export
                            </button>
                            <button id="tm-delete-all" class="tm-btn tm-btn-danger" title="Delete all cookies">
                                🗑️ Delete All
                            </button>
                        </div>
                    </div>

                    <div class="tm-search-section">
                        <div class="tm-search-wrapper">
                            <span class="tm-search-icon">🔍</span>
                            <input
                                type="text"
                                id="tm-search"
                                placeholder="Search cookies by name..."
                                autocomplete="off"
                            />
                            <span id="tm-search-count" class="tm-search-count"></span>
                        </div>
                    </div>

                    <div class="tm-sort-bar">
                        <span class="tm-sort-label">Sort by:</span>
                        <button class="tm-sort-btn" data-sort="name">Name</button>
                        <button class="tm-sort-btn" data-sort="length">Size</button>
                        <button class="tm-sort-btn tm-sort-active" data-sort="name">↑↓</button>
                    </div>

                    <div id="tm-cookie-list" class="tm-cookie-list"></div>
                </div>
            `;

            document.body.appendChild(this.container);
            this.injectStyles();
            this.cookieList = document.getElementById('tm-cookie-list');
            this.bindEvents();
            this.setupDragAndDrop();
        }

        injectStyles() {
            const style = document.createElement('style');
            style.textContent = `
                #tm-cookie-panel {
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    width: 500px;
                    max-height: 650px;
                    background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
                    color: #e2e8f0;
                    z-index: 999999;
                    border-radius: 16px;
                    overflow: hidden;
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
                    border: 1px solid rgba(71, 85, 105, 0.5);
                    backdrop-filter: blur(10px);
                    transition: all 0.3s ease;
                }

                #tm-cookie-panel.tm-minimized .tm-content {
                    display: none;
                }

                #tm-cookie-panel.tm-minimized {
                    max-height: 50px;
                }

                .tm-header {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    padding: 12px 16px;
                    background: rgba(30, 41, 59, 0.95);
                    backdrop-filter: blur(10px);
                    cursor: move;
                    border-bottom: 1px solid #334155;
                    user-select: none;
                }

                .tm-title {
                    display: flex;
                    align-items: center;
                    gap: 8px;
                    font-weight: 600;
                    font-size: 14px;
                }

                .tm-badge {
                    background: #3b82f6;
                    padding: 2px 6px;
                    border-radius: 12px;
                    font-size: 10px;
                    font-weight: 500;
                }

                .tm-header-actions {
                    display: flex;
                    gap: 8px;
                }

                .tm-icon-btn {
                    background: transparent;
                    border: none;
                    color: #94a3b8;
                    font-size: 20px;
                    cursor: pointer;
                    width: 28px;
                    height: 28px;
                    border-radius: 6px;
                    transition: all 0.2s;
                }

                .tm-icon-btn:hover {
                    background: #334155;
                    color: #e2e8f0;
                }

                .tm-content {
                    padding: 16px;
                }

                .tm-stats-bar {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-bottom: 12px;
                    padding: 8px 12px;
                    background: rgba(0, 0, 0, 0.2);
                    border-radius: 8px;
                    font-size: 11px;
                    color: #94a3b8;
                }

                .tm-controls {
                    margin-bottom: 12px;
                }

                .tm-control-group {
                    display: flex;
                    gap: 8px;
                    flex-wrap: wrap;
                }

                .tm-btn {
                    padding: 6px 12px;
                    border: none;
                    border-radius: 8px;
                    font-size: 12px;
                    font-weight: 500;
                    cursor: pointer;
                    transition: all 0.2s;
                    font-family: inherit;
                }

                .tm-btn-primary {
                    background: #3b82f6;
                    color: white;
                }

                .tm-btn-primary:hover {
                    background: #2563eb;
                    transform: translateY(-1px);
                }

                .tm-btn-secondary {
                    background: #334155;
                    color: #e2e8f0;
                }

                .tm-btn-secondary:hover {
                    background: #475569;
                    transform: translateY(-1px);
                }

                .tm-btn-danger {
                    background: #dc2626;
                    color: white;
                }

                .tm-btn-danger:hover {
                    background: #b91c1c;
                    transform: translateY(-1px);
                }

                .tm-search-section {
                    margin-bottom: 12px;
                }

                .tm-search-wrapper {
                    position: relative;
                }

                .tm-search-icon {
                    position: absolute;
                    left: 10px;
                    top: 50%;
                    transform: translateY(-50%);
                    font-size: 14px;
                    opacity: 0.5;
                }

                #tm-search {
                    width: 100%;
                    padding: 8px 8px 8px 32px;
                    background: #1e293b;
                    border: 1px solid #334155;
                    border-radius: 8px;
                    color: #e2e8f0;
                    font-size: 12px;
                    transition: all 0.2s;
                }

                #tm-search:focus {
                    outline: none;
                    border-color: #3b82f6;
                    background: #0f172a;
                }

                .tm-search-count {
                    position: absolute;
                    right: 10px;
                    top: 50%;
                    transform: translateY(-50%);
                    font-size: 11px;
                    color: #94a3b8;
                }

                .tm-sort-bar {
                    display: flex;
                    gap: 8px;
                    align-items: center;
                    margin-bottom: 12px;
                    padding-bottom: 8px;
                    border-bottom: 1px solid #334155;
                    font-size: 11px;
                }

                .tm-sort-label {
                    color: #94a3b8;
                }

                .tm-sort-btn {
                    background: transparent;
                    border: none;
                    color: #94a3b8;
                    cursor: pointer;
                    padding: 4px 8px;
                    border-radius: 4px;
                    font-size: 11px;
                    transition: all 0.2s;
                }

                .tm-sort-btn:hover {
                    background: #334155;
                    color: #e2e8f0;
                }

                .tm-sort-active {
                    color: #3b82f6;
                    font-weight: 600;
                }

                .tm-cookie-list {
                    overflow-y: auto;
                    max-height: 380px;
                }

                .tm-cookie-item {
                    background: rgba(30, 41, 59, 0.6);
                    margin-bottom: 8px;
                    padding: 12px;
                    border-radius: 10px;
                    transition: all 0.2s;
                    border-left: 3px solid #3b82f6;
                    position: relative;
                }

                .tm-cookie-item:hover {
                    background: rgba(51, 65, 85, 0.8);
                    transform: translateX(-2px);
                }

                .tm-cookie-name {
                    font-weight: 600;
                    color: #60a5fa;
                    font-size: 13px;
                    margin-bottom: 6px;
                    word-break: break-word;
                    padding-right: 60px;
                }

                .tm-cookie-value {
                    font-size: 11px;
                    color: #94a3b8;
                    word-break: break-all;
                    font-family: 'Courier New', monospace;
                    margin-bottom: 8px;
                }

                .tm-cookie-actions {
                    position: absolute;
                    top: 12px;
                    right: 12px;
                    display: flex;
                    gap: 6px;
                }

                .tm-cookie-action {
                    background: transparent;
                    border: none;
                    cursor: pointer;
                    font-size: 14px;
                    padding: 2px 4px;
                    border-radius: 4px;
                    transition: all 0.2s;
                }

                .tm-cookie-action:hover {
                    background: #475569;
                }

                .tm-cookie-size {
                    font-size: 9px;
                    color: #64748b;
                    display: inline-block;
                    margin-top: 4px;
                }

                .tm-empty-state {
                    text-align: center;
                    padding: 40px;
                    color: #64748b;
                }

                .tm-toast {
                    position: fixed;
                    bottom: 20px;
                    right: 540px;
                    background: #10b981;
                    color: white;
                    padding: 10px 16px;
                    border-radius: 8px;
                    font-size: 12px;
                    z-index: 1000000;
                    animation: slideIn 0.3s ease;
                }

                @keyframes slideIn {
                    from {
                        transform: translateX(100%);
                        opacity: 0;
                    }
                    to {
                        transform: translateX(0);
                        opacity: 1;
                    }
                }

                ::-webkit-scrollbar {
                    width: 6px;
                }

                ::-webkit-scrollbar-track {
                    background: #1e293b;
                    border-radius: 3px;
                }

                ::-webkit-scrollbar-thumb {
                    background: #475569;
                    border-radius: 3px;
                }

                ::-webkit-scrollbar-thumb:hover {
                    background: #64748b;
                }
            `;
            document.head.appendChild(style);
        }

        setupDragAndDrop() {
            const header = document.getElementById('tm-drag-handle');
            header.addEventListener('mousedown', (e) => {
                if (e.target.tagName === 'BUTTON') return;
                this.isDragging = true;
                const rect = this.container.getBoundingClientRect();
                this.dragOffset.x = e.clientX - rect.left;
                this.dragOffset.y = e.clientY - rect.top;
                this.container.style.transition = 'none';
            });

            document.addEventListener('mousemove', (e) => {
                if (!this.isDragging) return;
                const x = e.clientX - this.dragOffset.x;
                const y = e.clientY - this.dragOffset.y;
                this.container.style.left = x + 'px';
                this.container.style.top = y + 'px';
                this.container.style.right = 'auto';
            });

            document.addEventListener('mouseup', () => {
                this.isDragging = false;
                this.container.style.transition = '';
            });
        }

        setupKeyboardShortcuts() {
            document.addEventListener('keydown', (e) => {
                if (e.ctrlKey && e.key === 'c' && document.activeElement.id === 'tm-search') {
                    e.preventDefault();
                    this.copyCookies();
                }
                if (e.key === 'Escape') {
                    this.container.remove();
                }
            });
        }

        sortCookies(cookies, sortBy, direction) {
            return Object.entries(cookies).sort((a, b) => {
                let comparison = 0;
                if (sortBy === 'name') {
                    comparison = a[0].localeCompare(b[0]);
                } else if (sortBy === 'length') {
                    comparison = a[1].length - b[1].length;
                }
                return direction === 'asc' ? comparison : -comparison;
            });
        }

        renderCookies(filter = '') {
            this.cookieList.innerHTML = '';

            let filteredCookies = Object.entries(this.cookies);

            if (filter) {
                filteredCookies = filteredCookies.filter(([name]) =>
                    name.toLowerCase().includes(filter.toLowerCase())
                );

                const searchCount = document.getElementById('tm-search-count');
                if (searchCount) {
                    searchCount.textContent = `${filteredCookies.length} found`;
                }
            } else {
                const searchCount = document.getElementById('tm-search-count');
                if (searchCount) {
                    searchCount.textContent = '';
                }
            }

            const sortedCookies = this.sortCookies(Object.fromEntries(filteredCookies), this.currentSort, this.sortDirection);

            if (sortedCookies.length === 0) {
                this.cookieList.innerHTML = '<div class="tm-empty-state">🍪 No cookies found</div>';
                return;
            }

            for (const [name, data] of sortedCookies) {
                const item = document.createElement('div');
                item.className = 'tm-cookie-item';

                const truncatedValue = data.value.length > 100 ?
                    data.value.substring(0, 100) + '...' :
                    data.value;

                item.innerHTML = `
                    <div class="tm-cookie-name">${this.escapeHtml(name)}</div>
                    <div class="tm-cookie-value">${this.escapeHtml(truncatedValue)}</div>
                    <div class="tm-cookie-size">📏 ${data.length} chars</div>
                    <div class="tm-cookie-actions">
                        <button class="tm-cookie-action" data-action="copy" data-name="${this.escapeHtml(name)}" title="Copy value">📋</button>
                        <button class="tm-cookie-action" data-action="delete" data-name="${this.escapeHtml(name)}" title="Delete cookie">🗑️</button>
                    </div>
                `;

                const copyBtn = item.querySelector('[data-action="copy"]');
                const deleteBtn = item.querySelector('[data-action="delete"]');

                copyBtn.addEventListener('click', () => {
                    this.copySingleCookie(name);
                });

                deleteBtn.addEventListener('click', () => {
                    this.deleteCookie(name);
                });

                this.cookieList.appendChild(item);
            }
        }

        escapeHtml(str) {
            const div = document.createElement('div');
            div.textContent = str;
            return div.innerHTML;
        }

        showToast(message, isError = false) {
            const toast = document.createElement('div');
            toast.className = 'tm-toast';
            toast.style.background = isError ? '#ef4444' : '#10b981';
            toast.textContent = message;
            document.body.appendChild(toast);
            setTimeout(() => toast.remove(), 3000);
        }

        deleteCookie(name) {
            if (confirm(`Delete cookie "${name}"?`)) {
                document.cookie = `${encodeURIComponent(name)}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
                document.cookie = `${encodeURIComponent(name)}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${window.location.hostname}`;
                this.loadCookies();
                this.showToast(`✅ Deleted "${name}"`);
            }
        }

        deleteAllCookies() {
            if (confirm('⚠️ Delete ALL cookies for this domain? This action cannot be undone!')) {
                const cookies = Object.keys(this.cookies);
                cookies.forEach(name => {
                    document.cookie = `${encodeURIComponent(name)}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
                    document.cookie = `${encodeURIComponent(name)}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${window.location.hostname}`;
                });
                this.loadCookies();
                this.showToast(`🗑️ Deleted ${cookies.length} cookies`);
            }
        }

        copySingleCookie(name) {
            const value = this.cookies[name].value;
            GM_setClipboard(value);
            this.showToast(`📋 Copied "${name}" to clipboard`);
        }

        exportCookies() {
            const exportData = {};
            Object.entries(this.cookies).forEach(([name, data]) => {
                exportData[name] = data.value;
            });

            const blob = new Blob(
                [JSON.stringify(exportData, null, 2)],
                { type: 'application/json' }
            );
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `cookies_${window.location.hostname}_${Date.now()}.json`;
            a.click();
            URL.revokeObjectURL(url);
            this.showToast('💾 Cookies exported successfully');
        }

        copyCookies() {
            const exportData = {};
            Object.entries(this.cookies).forEach(([name, data]) => {
                exportData[name] = data.value;
            });
            GM_setClipboard(JSON.stringify(exportData, null, 2));
            this.showToast('📋 Cookies copied to clipboard');
        }

        bindEvents() {
            document.getElementById('tm-refresh').addEventListener('click', () => {
                this.loadCookies();
                this.showToast('🔄 Cookies refreshed');
            });

            document.getElementById('tm-copy').addEventListener('click', () => this.copyCookies());
            document.getElementById('tm-export').addEventListener('click', () => this.exportCookies());
            document.getElementById('tm-delete-all').addEventListener('click', () => this.deleteAllCookies());
            document.getElementById('tm-close').addEventListener('click', () => this.container.remove());

            document.getElementById('tm-minimize').addEventListener('click', () => {
                this.container.classList.toggle('tm-minimized');
                const minimizeBtn = document.getElementById('tm-minimize');
                minimizeBtn.textContent = this.container.classList.contains('tm-minimized') ? '□' : '−';
            });

            document.getElementById('tm-clear-filter').addEventListener('click', () => {
                const searchInput = document.getElementById('tm-search');
                searchInput.value = '';
                this.renderCookies('');
            });

            document.getElementById('tm-search').addEventListener('input', (event) => {
                this.renderCookies(event.target.value);
            });

            document.querySelectorAll('.tm-sort-btn[data-sort]').forEach(btn => {
                btn.addEventListener('click', () => {
                    const sortBy = btn.getAttribute('data-sort');
                    if (this.currentSort === sortBy) {
                        this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
                    } else {
                        this.currentSort = sortBy;
                        this.sortDirection = 'asc';
                    }

                    document.querySelectorAll('.tm-sort-btn').forEach(b => b.classList.remove('tm-sort-active'));
                    btn.classList.add('tm-sort-active');
                    this.renderCookies(document.getElementById('tm-search').value);
                });
            });
        }
    }

    new CookieGUI();
})();