Floating Link Menu

Customizable link menu.

As of 2025-08-26. See the latest version.

// ==UserScript==
// @name         Floating Link Menu
// @namespace    http://tampermonkey.net/
// @version      2.7 universal
// @description  Customizable link menu.
// @author       echoZ
// @license      MIT
// @match        *://*/*
// @exclude      *://*routerlogin.net/*
// @exclude      *://*192.168.1.1/*
// @exclude      *://*192.168.0.1/*
// @exclude      *://*my.bankofamerica.com/*
// @exclude      *://*wellsfargo.com/*
// @exclude      *://*chase.com/*
// @exclude      *://*citibank.com/*
// @exclude      *://*online.citi.com/*
// @exclude      *://*capitalone.com/*
// @exclude      *://*usbank.com/*
// @exclude      *://*paypal.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @run-at       document-start
// ==/UserScript==

(async function() {
    'use strict';

    // --- SCRIPT EXCLUSION LOGIC ---
    const excludedDomainsStorageKey = 'excludedUniversalDomains';
    const currentUrl = window.location.href;
    const excludedDomains = await GM_getValue(excludedDomainsStorageKey, []);
    const isExcluded = excludedDomains.some(domain => currentUrl.includes(domain));
    if (isExcluded) {
        return;
    }
    // --- END EXCLUSION LOGIC ---

    // --- Data Management using Tampermonkey's GM_ API ---
    const storageKey = 'universalLinkManagerLinks';
    const isBubbleHiddenStorageKey = 'isBubbleHidden';
    const buttonPositionStorageKey = 'bubblePosition';
    const themeStorageKey = 'universalLinkManagerTheme';

    const defaultLinks = [
        { label: 'Google', url: 'https://www.google.com/' },
        { label: 'Gemini AI', url: 'https://gemini.google.com/' },
        { label: 'OpenAI', url: 'https://www.openai.com/' }
    ];

    let isDeleteMode = false;
    let isExcludeDeleteMode = false;

    async function getLinks() {
        return await GM_getValue(storageKey, defaultLinks);
    }

    async function saveLinks(links) {
        await GM_setValue(storageKey, links);
    }

    async function getExcludedDomains() {
        return await GM_getValue(excludedDomainsStorageKey, []);
    }

    async function saveExcludedDomains(domains) {
        await GM_setValue(excludedDomainsStorageKey, domains);
    }

    async function getBubbleHiddenState() {
        return await GM_getValue(isBubbleHiddenStorageKey, false);
    }

    async function saveBubbleHiddenState(isHidden) {
        await GM_setValue(isBubbleHiddenStorageKey, isHidden);
    }

    async function getButtonPosition() {
        return await GM_getValue(buttonPositionStorageKey, { vertical: 'bottom', horizontal: 'right' });
    }

    async function saveButtonPosition(position) {
        await GM_setValue(buttonPositionStorageKey, position);
    }

    async function getTheme() {
        return await GM_getValue(themeStorageKey, 'default');
    }

    async function saveTheme(theme) {
        await GM_setValue(themeStorageKey, theme);
    }

    // --- Style and Themes ---
    const themes = {
        default: `
            #floatingMenu, #universalLinkManagerUI, #bubbleMenu { background-color: #222; border: 2px solid #0ff; box-shadow: 0 0 10px rgba(0,255,255,0.7); }
            #linkList a, .exclude-wrapper span { color: #fff; background-color: #333; border: 1px solid #0ff; }
            #linkList a:hover { background-color: #0ff; color: #000; }
            #menuControls button, #backupSection button, #positionControls button, .modal-button, #bubbleMenu button { color: #0ff; border: 1px solid #0ff; background-color: #444; }
            #menuControls button:hover, #backupSection button:hover, #positionControls button:hover, .modal-button:hover, #bubbleMenu button:hover { background-color: #0ff; color: #000; }
            #linkForm input, #excludeSection input { border: 1px solid #0ff; background-color: #333; color: #fff; }
            #linkForm h3, #excludeSection h3, #backupSection h3, #positionControls h3 { color: #fff; }
            .delete-link-button, .delete-exclude-button { background-color: #a00; border: 1px solid #f00; color: #fff; }
            .delete-link-button:hover, .delete-exclude-button:hover { background-color: #f00; }
            .active { background-color: #0ff; color: #000 !important; }
        `,
        highContrast: `
            #floatingMenu, #universalLinkManagerUI, #bubbleMenu { background-color: #000; border: 2px solid #ffff00; box-shadow: 0 0 15px rgba(255,255,0,0.9); }
            #linkList a, .exclude-wrapper span { color: #ffff00; background-color: #000; border: 1px solid #ffff00; text-shadow: 0 0 5px #ffff00; font-weight: bold; }
            #linkList a:hover { background-color: #ffff00; color: #000; text-shadow: none; }
            #menuControls button, #backupSection button, #positionControls button, .modal-button, #bubbleMenu button { color: #ffff00; border: 1px solid #ffff00; background-color: #333; }
            #menuControls button:hover, #backupSection button:hover, #positionControls button:hover, .modal-button:hover, #bubbleMenu button:hover { background-color: #ffff00; color: #000; }
            #linkForm input, #excludeSection input { border: 1px solid #ffff00; background-color: #000; color: #ffff00; }
            #linkForm h3, #excludeSection h3, #backupSection h3, #positionControls h3 { color: #ffff00; }
            .delete-link-button, .delete-exclude-button { background-color: #ff0000; border: 1px solid #ff0000; color: #ffff00; }
            .delete-link-button:hover, .delete-exclude-button:hover { background-color: #ff5555; }
            .active { background-color: #ffff00; color: #000 !important; }
        `
    };

    const baseStyle = `
        @keyframes pulse {
            0% { transform: scale(1); box-shadow: 0 0 15px 3px #0ff, 0 0 30px 10px #0ff; }
            50% { transform: scale(1.05); box-shadow: 0 0 20px 5px #0ff, 0 0 40px 15px #0ff; }
            100% { transform: scale(1); box-shadow: 0 0 15px 3px #0ff, 0 0 30px 10px #0ff; }
        }
        @keyframes neonGlow {
            0% { box-shadow: 0 0 10px rgba(0,255,255,0.7); }
            50% { box-shadow: 0 0 15px rgba(0,255,255,0.9), 0 0 25px rgba(0,255,255,0.6); }
            100% { box-shadow: 0 0 10px rgba(0,255,255,0.7); }
        }

        #customFloatingBubble {
            position: fixed;
            width: 60px;
            height: 60px;
            background-color: #0ff;
            border-radius: 50%;
            box-shadow: 0 0 15px 3px #0ff, 0 0 30px 10px #0ff;
            cursor: pointer;
            z-index: 9999999;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 36px;
            font-weight: 900;
            color: #001f3f;
            user-select: none;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            transition: transform 0.2s ease, box-shadow 0.2s ease, top 0.2s ease, bottom 0.2s ease, left 0.2s ease, right 0.2s ease;
            animation: pulse 3s infinite ease-in-out;
        }
        #customFloatingBubble:hover {
            transform: scale(1.15);
            box-shadow: 0 0 20px 5px #0ff, 0 0 40px 15px #0ff;
        }
        #universalLinkManagerUI {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 350px;
            border-radius: 8px;
            padding: 15px;
            z-index: 9999998;
            display: none;
            flex-direction: column;
            gap: 15px;
            max-height: 90vh;
            overflow-y: auto;
            animation: neonGlow 4s infinite ease-in-out;
        }
        #bubbleMenu {
            position: fixed;
            z-index: 9999999;
            padding: 10px;
            border-radius: 8px;
            display: none;
            flex-direction: column;
            gap: 8px;
            animation: neonGlow 4s infinite ease-in-out;
        }
        #bubbleMenu button {
            transition: background-color 0.2s, color 0.2s;
        }
        #ui-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            border-bottom: 1px solid #555;
            padding-bottom: 10px;
        }
        #ui-header h2 {
            margin: 0;
            color: #0ff;
            text-shadow: 0 0 5px #0ff;
        }
        #closeUI {
            background: none;
            border: none;
            color: #fff;
            font-size: 24px;
            cursor: pointer;
            padding: 0;
            width: 30px;
            height: 30px;
            border-radius: 50%;
            transition: all 0.2s ease;
        }
        #closeUI:hover {
            background-color: #f00;
            transform: scale(1.1);
        }
        #linkList, #excludeList {
            display: flex;
            flex-direction: column;
            gap: 5px;
        }
        .link-wrapper, .exclude-wrapper {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        #linkList a, .exclude-wrapper span {
            flex-grow: 1;
            padding: 8px;
            text-align: center;
            text-decoration: none;
            border-radius: 5px;
            transition: background-color 0.2s ease, color 0.2s ease;
            text-shadow: 0 0 3px currentColor;
            font-size: 14px;
        }
        .delete-link-button, .delete-exclude-button {
            width: 30px;
            height: 30px;
            border-radius: 50%;
            cursor: pointer;
            font-weight: bold;
            transition: background-color 0.2s ease;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 0;
        }
        #menuControls {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;
            gap: 5px;
        }
        #menuControls button, .modal-button {
            padding: 8px 12px;
            border-radius: 5px;
            cursor: pointer;
            flex: 1 1 45%;
            font-size: 12px;
            text-align: center;
        }
        #linkForm, #excludeSection, #backupSection, #positionControls {
            display: flex;
            flex-direction: column;
            gap: 5px;
            padding-top: 10px;
            border-top: 1px solid #444;
        }
        #linkForm h3, #excludeSection h3, #backupSection h3, #positionControls h3 {
            margin: 0;
            text-align: center;
        }
        #linkForm input, #excludeSection input {
            padding: 8px;
            border-radius: 5px;
        }
        #backupSection button {
            flex: 1;
            font-size: 14px;
        }
        #showBubbleButton {
            position: fixed;
            width: 60px;
            height: 60px;
            cursor: pointer;
            z-index: 9999997;
            background-color: transparent;
            border: none;
            user-select: none;
        }
        #positionControls .position-buttons {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 5px;
        }
        .import-buttons {
            display: flex;
            gap: 5px;
        }
        .import-buttons button {
            flex: 1;
        }
    `;

    GM_addStyle(baseStyle);

    let bubble = null;
    let mainUI = null;
    let showBubbleButton = null;
    let bubbleMenu = null;

    function populateLinkList(links, linkListElement) {
        linkListElement.innerHTML = '';
        links.forEach((linkData, index) => {
            const linkWrapper = document.createElement('div');
            linkWrapper.className = 'link-wrapper';

            const link = document.createElement('a');
            link.href = linkData.url;
            link.textContent = linkData.label;
            link.target = '_blank';

            linkWrapper.appendChild(link);

            if (isDeleteMode) {
                const deleteButton = document.createElement('button');
                deleteButton.className = 'delete-link-button';
                deleteButton.textContent = 'x';
                deleteButton.addEventListener('click', async (event) => {
                    event.preventDefault();
                    links.splice(index, 1);
                    await saveLinks(links);
                    populateLinkList(links, linkListElement);
                });
                linkWrapper.appendChild(deleteButton);
            }
            linkListElement.appendChild(linkWrapper);
        });
    }

    function populateExcludeList(domains, excludeListElement) {
        excludeListElement.innerHTML = '';
        domains.forEach((domain, index) => {
            const domainWrapper = document.createElement('div');
            domainWrapper.className = 'exclude-wrapper';

            const domainLabel = document.createElement('span');
            domainLabel.textContent = domain;
            domainWrapper.appendChild(domainLabel);

            if (isExcludeDeleteMode) {
                const deleteButton = document.createElement('button');
                deleteButton.className = 'delete-exclude-button';
                deleteButton.textContent = 'x';
                deleteButton.addEventListener('click', async (event) => {
                    event.preventDefault();
                    domains.splice(index, 1);
                    await saveExcludedDomains(domains);
                    populateExcludeList(domains, excludeListElement);
                });
                domainWrapper.appendChild(deleteButton);
            }
            excludeListElement.appendChild(domainWrapper);
        });
    }

    function applyButtonPosition(position) {
        if (bubble) {
            bubble.style.top = '';
            bubble.style.left = '';
            bubble.style.bottom = '';
            bubble.style.right = '';
            bubble.style[position.vertical] = '30px';
            bubble.style[position.horizontal] = '30px';
        }
        if (showBubbleButton) {
            showBubbleButton.style.top = '';
            showBubbleButton.style.left = '';
            showBubbleButton.style.bottom = '';
            showBubbleButton.style.right = '';
            showBubbleButton.style[position.vertical] = '30px';
            showBubbleButton.style[position.horizontal] = '30px';
        }
        if (bubbleMenu) {
            bubbleMenu.style.top = '';
            bubbleMenu.style.left = '';
            bubbleMenu.style.bottom = '';
            bubbleMenu.style.right = '';

            if (position.vertical === 'top') {
                bubbleMenu.style.top = '100px';
            } else {
                bubbleMenu.style.bottom = '100px';
            }

            if (position.horizontal === 'left') {
                bubbleMenu.style.left = '30px';
            } else {
                bubbleMenu.style.right = '30px';
            }
        }

        const positionButtons = document.querySelectorAll('#positionControls button');
        positionButtons.forEach(btn => {
            btn.classList.remove('active');
        });
        const activeBtnId = `position-${position.vertical}-${position.horizontal}`;
        const activeBtn = document.getElementById(activeBtnId);
        if (activeBtn) {
            activeBtn.classList.add('active');
        }
    }

    function applyTheme(themeName) {
        const styleElement = document.getElementById('universalLinkManagerStyle');
        if (styleElement) {
            styleElement.innerHTML = `${baseStyle}\n${themes[themeName]}\n`;
        }
    }

    async function initializeScript() {
        if (document.getElementById('customFloatingBubble')) {
            return;
        }

        const buttonPosition = await getButtonPosition();
        const currentTheme = await getTheme();
        
        const style = document.createElement('style');
        style.id = 'universalLinkManagerStyle';
        document.head.appendChild(style);
        applyTheme(currentTheme);

        // Create the bubble
        bubble = document.createElement('div');
        bubble.id = 'customFloatingBubble';
        bubble.textContent = 'λ';
        document.body.appendChild(bubble);

        // Create the mini bubble menu
        bubbleMenu = document.createElement('div');
        bubbleMenu.id = 'bubbleMenu';
        bubbleMenu.innerHTML = `
            <button id="instantAddButton">Add This Site</button>
            <button id="showFullMenuButton">Settings</button>
        `;
        document.body.appendChild(bubbleMenu);

        // Create the main modal UI
        mainUI = document.createElement('div');
        mainUI.id = 'universalLinkManagerUI';
        mainUI.innerHTML = `
            <div id="ui-header">
                <h2>Universal Links</h2>
                <button id="closeUI">X</button>
            </div>
            <div id="ui-content">
                <div id="linkList"></div>
                <div id="linkForm">
                    <h3>Add New Link</h3>
                    <input type="text" id="linkLabel" placeholder="Label (e.g. My Site)">
                    <input type="text" id="linkUrl" placeholder="URL (e.g. https://example.com)">
                    <button id="saveLinkButton" class="modal-button">Save</button>
                </div>
                <div id="excludeSection">
                    <h3>Excluded Websites</h3>
                    <div id="excludeList"></div>
                    <input type="text" id="excludeUrl" placeholder="Domain (e.g. example.com)">
                    <button id="saveExcludeButton" class="modal-button">Add Exclude</button>
                    <button id="deleteExcludeButton" class="modal-button">Delete Excludes</button>
                </div>
                <div id="backupSection">
                    <h3>Backup & Restore</h3>
                    <div id="exportWrapper">
                        <button id="exportButton" class="modal-button">Export</button>
                    </div>
                    <div id="importWrapper">
                        <button id="importButton" class="modal-button">Import</button>
                    </div>
                </div>
                <div id="positionControls">
                    <h3>Button Position</h3>
                    <div class="position-buttons">
                        <button id="position-top-left" class="modal-button">Top-Left</button>
                        <button id="position-top-right" class="modal-button">Top-Right</button>
                        <button id="position-bottom-left" class="modal-button">Bottom-Left</button>
                        <button id="position-bottom-right" class="modal-button">Bottom-Right</button>
                    </div>
                </div>
                <div id="menuControls">
                    <button id="deleteLinksButton" class="modal-button">Delete Links</button>
                    <button id="themeButton" class="modal-button">Theme</button>
                    <button id="hideButton" class="modal-button">Hide Button</button>
                </div>
            </div>
        `;
        document.body.appendChild(mainUI);
        
        // Create the invisible show bubble button
        showBubbleButton = document.createElement('div');
        showBubbleButton.id = 'showBubbleButton';
        document.body.appendChild(showBubbleButton);

        // Load initial state and position
        applyButtonPosition(buttonPosition);
        const isHidden = await getBubbleHiddenState();
        bubble.style.display = isHidden ? 'none' : 'flex';
        showBubbleButton.style.display = isHidden ? 'block' : 'none';

        // --- Event Listeners ---

        // NEW: Keyboard shortcut to toggle the main UI
        document.addEventListener('keydown', async (event) => {
            // Check for Ctrl + Alt + U
            if (event.ctrlKey && event.altKey && event.key === 'u') {
                const isVisible = mainUI.style.display === 'flex';
                if (isVisible) {
                    mainUI.style.display = 'none';
                } else {
                    const links = await getLinks();
                    const excluded = await getExcludedDomains();
                    populateLinkList(links, mainUI.querySelector('#linkList'));
                    populateExcludeList(excluded, mainUI.querySelector('#excludeList'));
                    mainUI.style.display = 'flex';
                }
                event.preventDefault(); // Prevents the browser's default action
            }
        });

        // Bubble click to toggle the mini-menu
        bubble.addEventListener('click', async () => {
            const isVisible = bubbleMenu.style.display === 'flex';
            bubbleMenu.style.display = isVisible ? 'none' : 'flex';
        });

        // Triple-click logic for bubble
        let bubbleClickCount = 0;
        let bubbleClickTimer = null;
        bubble.addEventListener('click', () => {
            bubbleClickCount++;
            if (bubbleClickTimer) clearTimeout(bubbleClickTimer);
            bubbleClickTimer = setTimeout(() => {
                bubbleClickCount = 0;
            }, 300);

            if (bubbleClickCount === 3) {
                clearTimeout(bubbleClickTimer);
                bubble.style.display = 'none';
                showBubbleButton.style.display = 'block';
                mainUI.style.display = 'none';
                bubbleMenu.style.display = 'none';
                saveBubbleHiddenState(true);
                bubbleClickCount = 0;
            }
        });

        // Triple-click logic for showBubbleButton
        let restoreClickCount = 0;
        let restoreClickTimer = null;
        showBubbleButton.addEventListener('click', () => {
            restoreClickCount++;
            if (restoreClickTimer) clearTimeout(restoreClickTimer);
            restoreClickTimer = setTimeout(() => {
                restoreClickCount = 0;
            }, 400);

            if (restoreClickCount === 3) {
                clearTimeout(restoreClickTimer);
                bubble.style.display = 'flex';
                showBubbleButton.style.display = 'none';
                saveBubbleHiddenState(false);
                restoreClickCount = 0;
            }
        });
        
        // Instant Add Button
        bubbleMenu.querySelector('#instantAddButton').addEventListener('click', async () => {
            const title = document.title;
            const url = window.location.href;
            const links = await getLinks();
            
            links.push({ label: title, url: url });
            await saveLinks(links);
            
            bubbleMenu.style.display = 'none';
            const excluded = await getExcludedDomains();
            populateLinkList(links, mainUI.querySelector('#linkList'));
            populateExcludeList(excluded, mainUI.querySelector('#excludeList'));
            mainUI.style.display = 'flex';
        });

        // Show Full Menu Button
        bubbleMenu.querySelector('#showFullMenuButton').addEventListener('click', async () => {
            bubbleMenu.style.display = 'none';
            const links = await getLinks();
            const excluded = await getExcludedDomains();
            populateLinkList(links, mainUI.querySelector('#linkList'));
            populateExcludeList(excluded, mainUI.querySelector('#excludeList'));
            mainUI.style.display = 'flex';
        });

        mainUI.querySelector('#closeUI').addEventListener('click', () => {
            mainUI.style.display = 'none';
        });

        mainUI.querySelector('#hideButton').addEventListener('click', () => {
            bubble.style.display = 'none';
            showBubbleButton.style.display = 'block';
            mainUI.style.display = 'none';
            bubbleMenu.style.display = 'none';
            saveBubbleHiddenState(true);
        });

        mainUI.querySelector('#saveLinkButton').addEventListener('click', async () => {
            const labelInput = mainUI.querySelector('#linkLabel');
            const urlInput = mainUI.querySelector('#linkUrl');
            const label = labelInput.value.trim();
            const url = urlInput.value.trim();
            if (label && url) {
                try {
                    new URL(url);
                    const links = await getLinks();
                    links.push({ label, url });
                    await saveLinks(links);
                    populateLinkList(links, mainUI.querySelector('#linkList'));
                    labelInput.value = '';
                    urlInput.value = '';
                } catch (e) {
                    alert('Please enter a valid URL (e.g., https://example.com).');
                }
            } else {
                alert('Please enter both a label and a URL.');
            }
        });

        mainUI.querySelector('#deleteLinksButton').addEventListener('click', async () => {
            isDeleteMode = !isDeleteMode;
            const deleteButton = mainUI.querySelector('#deleteLinksButton');
            deleteButton.textContent = isDeleteMode ? 'Exit Delete' : 'Delete Links';
            const links = await getLinks();
            populateLinkList(links, mainUI.querySelector('#linkList'));
        });

        mainUI.querySelector('#themeButton').addEventListener('click', async () => {
            const currentTheme = await getTheme();
            const newTheme = currentTheme === 'default' ? 'highContrast' : 'default';
            await saveTheme(newTheme);
            applyTheme(newTheme);
            const themeButton = mainUI.querySelector('#themeButton');
            themeButton.textContent = newTheme === 'default' ? 'Theme' : 'Default';
        });

        mainUI.querySelector('#saveExcludeButton').addEventListener('click', async () => {
            const domainInput = mainUI.querySelector('#excludeUrl');
            const domain = domainInput.value.trim();
            if (domain) {
                const excluded = await getExcludedDomains();
                if (!excluded.includes(domain)) {
                    excluded.push(domain);
                    await saveExcludedDomains(excluded);
                    populateExcludeList(excluded, mainUI.querySelector('#excludeList'));
                    domainInput.value = '';
                } else {
                    alert('This domain is already on the exclusion list.');
                }
            } else {
                alert('Please enter a domain to exclude.');
            }
        });

        mainUI.querySelector('#deleteExcludeButton').addEventListener('click', async () => {
            isExcludeDeleteMode = !isExcludeDeleteMode;
            const deleteExcludeButton = mainUI.querySelector('#deleteExcludeButton');
            deleteExcludeButton.textContent = isExcludeDeleteMode ? 'Exit Exclude Delete' : 'Delete Excludes';
            const excluded = await getExcludedDomains();
            populateExcludeList(excluded, mainUI.querySelector('#excludeList'));
        });

        mainUI.querySelector('#positionControls').querySelectorAll('button').forEach(button => {
            button.addEventListener('click', async (event) => {
                const id = event.target.id;
                const parts = id.split('-');
                const newPosition = { vertical: parts[1], horizontal: parts[2] };
                await saveButtonPosition(newPosition);
                applyButtonPosition(newPosition);
            });
        });

        mainUI.querySelector('#exportWrapper').addEventListener('click', async (event) => {
            const button = event.target;
            if (button.id === 'exportButton') {
                if (button.textContent === 'Export') {
                    const links = await getLinks();
                    const exportData = JSON.stringify(links, null, 2);
                    mainUI.querySelector('#exportWrapper').innerHTML = `
                        <textarea readonly style="width:100%; height:100px;">${exportData}</textarea>
                        <button id="exportButton" class="modal-button">Close</button>
                    `;
                } else {
                    mainUI.querySelector('#exportWrapper').innerHTML = `<button id="exportButton" class="modal-button">Export</button>`;
                }
            }
        });

        mainUI.querySelector('#importWrapper').addEventListener('click', async (event) => {
            const button = event.target;
            if (button.id === 'importButton') {
                if (button.textContent === 'Import') {
                    mainUI.querySelector('#importWrapper').innerHTML = `
                        <textarea placeholder="Paste your link data here..." style="width:100%; height:100px;"></textarea>
                        <div class="import-buttons">
                            <button id="loadButton" class="modal-button">Load</button>
                            <button id="importButton" class="modal-button">Cancel</button>
                        </div>
                    `;
                } else {
                    mainUI.querySelector('#importWrapper').innerHTML = `<button id="importButton" class="modal-button">Import</button>`;
                }
            } else if (button.id === 'loadButton') {
                const dataTextarea = mainUI.querySelector('textarea');
                if (dataTextarea) {
                    const data = dataTextarea.value.trim();
                    if (!data) {
                        alert('Please paste the link data.');
                        return;
                    }
                    try {
                        const importedLinks = JSON.parse(data);
                        if (Array.isArray(importedLinks)) {
                            await saveLinks(importedLinks);
                            const links = await getLinks();
                            populateLinkList(links, mainUI.querySelector('#linkList'));
                            alert('Links imported successfully!');
                            mainUI.querySelector('#importWrapper').innerHTML = `<button id="importButton" class="modal-button">Import</button>`;
                        } else {
                            alert('Invalid data format. Please paste the correct JSON data.');
                        }
                    } catch (e) {
                        alert('Invalid JSON format. Error: ' + e.message);
                    }
                }
            }
        });
    }

    if (document.body) {
        initializeScript();
    } else {
        document.addEventListener('DOMContentLoaded', initializeScript);
    }
})();