Reddit Emoji Picker Pro (updated with newer code)

Professional Reddit Emoji Picker with Modern UI

// ==UserScript==
// @name         Reddit Emoji Picker Pro (updated with newer code)
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  Professional Reddit Emoji Picker with Modern UI
// @author       sadE
// @match        https://*.reddit.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-idle
// ==/UserScript==

(() => {
    'use strict';

    // Emoji data array (keeping original)
    const emotes = [{code:'[emote:t5_33td5:59888](http://img)',name:'Clueless',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Clueless.png'},{code:'[emote:t5_33td5:59889](http://img)',name:'Okayeg',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Okayeg.png'},{code:'[emote:t5_33td5:59890](http://img)',name:'cmonBruh',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/cmonBruh.png'},{code:'[emote:t5_33td5:59891](http://img)',name:'Copesen',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Copesen.png'},{code:'[emote:t5_33td5:59892](http://img)',name:'forsenCD',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/forsenCD.png'},{code:'[emote:t5_33td5:59893](http://img)',name:'forsenE',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/forsenE.png'},{code:'[emote:t5_33td5:59894](http://img)',name:'tf',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/tf.png'},{code:'[emote:t5_33td5:59895](http://img)',name:'FeelsOkayMan',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/FeelsOkayMan.png'},{code:'[emote:t5_33td5:59896](http://img)',name:'gachiGASM',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/gachiGASM.png'},{code:'[emote:t5_33td5:59897](http://img)',name:'monkaOMEGA',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/monkaOMEGA.png'},{code:'[emote:t5_33td5:59898](http://img)',name:'LULE',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/LULE.png'},{code:'[emote:t5_33td5:59899](http://img)',name:'OMEGALUL',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/OMEGALUL.png'},{code:'[emote:t5_33td5:59900](http://img)',name:'PagMan',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/PagMan.png'},{code:'[emote:t5_33td5:59901](http://img)',name:'forsenBased',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/forsenBased.png'},{code:'[emote:t5_33td5:59902](http://img)',name:'Sadeg',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Sadeg.png'},{code:'[emote:t5_33td5:59903](http://img)',name:'forsenAlright',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/forsenAlright.png'},{code:'[emote:t5_33td5:59904](http://img)',name:'forsenLevel',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/forsenLevel.png'},{code:'[emote:t5_33td5:59905](http://img)',name:'pepeLaugh',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/pepeLaugh.png'},{code:'[emote:t5_33td5:59906](http://img)',name:'forsenDespair',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/forsenDespair.png'},{code:'[emote:t5_33td5:53915](http://img)',name:'sadE',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/sadE.png'},{code:'[emote:t5_33td5:53373](http://img)',name:'forsenMaxLevel',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/forsenMaxLevel.png'},{code:'[emote:t5_33td5:9486](http://img)',name:'maoE',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/maoE.png'},{code:'[emote:t5_33td5:9683](http://img)',name:'Wutface',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Wutface.png'},{code:'[emote:t5_33td5:5322](http://img)',name:'MegaLUL',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/MegaLUL.png'},{code:'[emote:t5_33td5:5359](http://img)',name:'Docsen',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Docsen.png'},{code:'[emote:t5_33td5:10257](http://img)',name:'amongE',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/amongE.png'},{code:'[emote:t5_33td5:9671](http://img)',name:'Batchest',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Batchest.png'},{code:'[emote:t5_33td5:53371](http://img)',name:'forsenNugget',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/forsenNugget.png'},{code:'[emote:t5_33td5:53390](http://img)',name:'LongHairMaxLevel',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/LongHairMaxLevel.png'},{code:'[emote:t5_33td5:54526](http://img)',name:'Pewds',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Pewds.png'},{code:'[emote:t5_33td5:53563](http://img)',name:'monkaLaugh',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/monkaLaugh.png'},{code:'[emote:t5_33td5:55418](http://img)',name:'muv',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/muv.png'},{code:'[emote:t5_33td5:55894](http://img)',name:'snowman',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/snowman.png'},{code:'[emote:t5_33td5:55905](http://img)',name:'bbangrE',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/bbangrE.png'},{code:'[emote:t5_33td5:56633](http://img)',name:'WeebsOut',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/WeebsOut.png'},{code:'[emote:t5_33td5:56664](http://img)',name:'freakE',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/freakE.png'},{code:'[emote:t5_33td5:57649](http://img)',name:'emiru',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/emiru.png'},{code:'[emote:t5_33td5:58897](http://img)',name:'wahhabi',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/wahhabi.png'},{code:'[emote:t5_33td5:58898](http://img)',name:'thisIsYouOnIslam',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/thisIsYouOnIslam.png'},{code:'[emote:t5_33td5:58899](http://img)',name:'familyPhoto',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/familyPhoto.png'},{code:'[emote:t5_33td5:58900](http://img)',name:'sheikh',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/sheikh.png'},{code:'[emote:t5_33td5:58901](http://img)',name:'Stoning',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Stoning.png'},{code:'[emote:t5_33td5:58913](http://img)',name:'turban',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/turban.png'},{code:'[emote:t5_33td5:58914](http://img)',name:'quranPepe',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/quranPepe.png'},{code:'[emote:t5_33td5:58948](http://img)',name:'desertLevel',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/desertLevel.png'},{code:'[emote:t5_33td5:58949](http://img)',name:'hesHalal',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/hesHalal.png'},{code:'[emote:t5_33td5:59909](http://img)',name:'Tomfoolery',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/Tomfoolery.png'},{code:'[emote:t5_33td5:60326](http://img)',name:'salute',url:'https://raw.githubusercontent.com/rarestemotes/emotes/main/images/salute.png'}];

    let config = GM_getValue('redditEmojiPickerConfig', { autoSwitchToMarkdown: true });
    let hasShownFormattingBar = false, hasSwitchedToMarkdown = false, mutationObserver = null;
    const addedElements = new Map();

    // Modern CSS with professional design system
    const styles = document.createElement('style');
    styles.textContent = `
        /* Button - Clean, minimal with subtle hover */
        .emoji-btn {
            background: transparent;
            border: none;
            border-radius: 6px;
            width: 32px;
            height: 32px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: all 0.15s cubic-bezier(0.4, 0.0, 0.2, 1);
            color: #878a8c;
        }
        .emoji-btn:hover {
            background: rgba(26, 26, 27, 0.1);
            color: #1c1c1c;
            transform: scale(1.05);
        }
        .emoji-btn svg {
            width: 18px;
            height: 18px;
        }

        /* Picker - Modern card design with backdrop blur */
        .emoji-picker {
            position: absolute;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(16px);
            border: 1px solid rgba(215, 218, 220, 0.4);
            border-radius: 12px;
            padding: 8px;
            width: 280px;
            max-height: 240px;
            overflow-y: auto;
            z-index: 10000;
            display: none;
            box-shadow:
                0 4px 6px -1px rgba(0, 0, 0, 0.1),
                0 2px 4px -1px rgba(0, 0, 0, 0.06),
                0 20px 25px -5px rgba(0, 0, 0, 0.1);
            display: grid;
            grid-template-columns: repeat(8, 1fr);
            gap: 4px;
        }

        /* Dark mode support */
        @media (prefers-color-scheme: dark) {
            .emoji-picker {
                background: rgba(26, 26, 27, 0.95);
                border-color: rgba(52, 53, 54, 0.6);
            }
            .emoji-btn:hover {
                background: rgba(215, 218, 220, 0.1);
                color: #d7dadc;
            }
        }

        /* Emoji items - Rounded with smooth interactions */
        .emoji-item {
            width: 28px;
            height: 28px;
            cursor: pointer;
            border-radius: 6px;
            padding: 2px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.12s ease;
            position: relative;
        }
        .emoji-item:hover {
            background: rgba(0, 121, 211, 0.1);
            transform: scale(1.1);
        }
        .emoji-item img {
            width: 100%;
            height: 100%;
            object-fit: contain;
        }

        /* Settings panel - Compact and clean */
        .emoji-settings {
            position: absolute;
            background: rgba(255, 255, 255, 0.98);
            backdrop-filter: blur(16px);
            border: 1px solid rgba(215, 218, 220, 0.4);
            border-radius: 8px;
            padding: 12px;
            width: 200px;
            z-index: 10001;
            display: none;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
        }
        @media (prefers-color-scheme: dark) {
            .emoji-settings {
                background: rgba(26, 26, 27, 0.98);
                border-color: rgba(52, 53, 54, 0.6);
                color: #d7dadc;
            }
        }

        .emoji-settings h3 {
            margin: 0 0 8px 0;
            font-size: 13px;
            font-weight: 600;
            color: inherit;
        }
        .emoji-settings label {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 12px;
            cursor: pointer;
        }
        .emoji-settings button {
            width: 100%;
            background: #0079d3;
            color: white;
            border: none;
            border-radius: 4px;
            padding: 6px;
            margin-top: 8px;
            font-size: 11px;
            cursor: pointer;
            transition: background 0.15s;
        }
        .emoji-settings button:hover {
            background: #0061a9;
        }

        /* Wrapper and status */
        .emoji-wrapper {
            position: relative;
            display: inline-flex;
            align-items: center;
            gap: 4px;
            margin: 4px 0;
        }
        .emoji-status {
            position: absolute;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 11px;
            bottom: 100%;
            left: 0;
            margin-bottom: 4px;
            display: none;
            z-index: 10002;
        }

        /* Scrollbar styling for webkit browsers */
        .emoji-picker::-webkit-scrollbar {
            width: 4px;
        }
        .emoji-picker::-webkit-scrollbar-track {
            background: transparent;
        }
        .emoji-picker::-webkit-scrollbar-thumb {
            background: rgba(0, 0, 0, 0.2);
            border-radius: 2px;
        }
    `;
    document.head.appendChild(styles);

    // Create main button with modern icon
    const createButton = () => {
        const btn = document.createElement('button');
        btn.className = 'emoji-btn';
        btn.title = 'Emojis';
        btn.innerHTML = `<svg viewBox="0 0 24 24" fill="currentColor">
            <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
        </svg>`;
        btn.addEventListener('click', togglePicker, true);
        return btn;
    };

    // Toggle picker visibility
    const togglePicker = (e) => {
        e.preventDefault();
        e.stopPropagation();
        const picker = e.currentTarget.parentNode.querySelector('.emoji-picker');
        const isHidden = picker.style.display === 'none';

        // Close all other pickers
        document.querySelectorAll('.emoji-picker, .emoji-settings').forEach(p => p.style.display = 'none');

        if (isHidden) {
            picker.style.display = 'grid';
        }
    };

    // Create settings button
    const createSettingsBtn = () => {
        const btn = document.createElement('button');
        btn.className = 'emoji-btn';
        btn.title = 'Settings';
        btn.innerHTML = `<svg viewBox="0 0 24 24" fill="currentColor">
            <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>
        </svg>`;
        btn.addEventListener('click', toggleSettings, true);
        return btn;
    };

    // Toggle settings panel
    const toggleSettings = (e) => {
        e.preventDefault();
        e.stopPropagation();
        const panel = e.currentTarget.parentNode.querySelector('.emoji-settings');
        const isHidden = panel.style.display === 'none';

        document.querySelectorAll('.emoji-settings').forEach(p => p.style.display = 'none');

        if (isHidden) {
            panel.style.display = 'block';
        }
    };

    // Show status message
    const showStatus = (wrapper, message, duration = 2000) => {
        const status = wrapper.querySelector('.emoji-status');
        if (status) {
            status.textContent = message;
            status.style.display = 'block';
            setTimeout(() => status.style.display = 'none', duration);
        }
    };

    // Create settings panel
    const createSettings = () => {
        const panel = document.createElement('div');
        panel.className = 'emoji-settings';
        panel.innerHTML = `
            <h3>Settings</h3>
            <label>
                <input type="checkbox" id="auto-markdown" ${config.autoSwitchToMarkdown ? 'checked' : ''}>
                Auto-switch to Markdown
            </label>
            <button type="button">Save</button>
        `;

        panel.querySelector('button').addEventListener('click', (e) => {
            e.preventDefault();
            const checkbox = panel.querySelector('#auto-markdown');
            const prevConfig = {...config};

            config.autoSwitchToMarkdown = checkbox.checked;
            GM_setValue('redditEmojiPickerConfig', config);

            if (config.autoSwitchToMarkdown && !prevConfig.autoSwitchToMarkdown) {
                enableAutoSwitch();
            } else if (!config.autoSwitchToMarkdown && prevConfig.autoSwitchToMarkdown) {
                disableAutoSwitch();
            }

            panel.style.display = 'none';
            showStatus(panel.parentNode, 'Saved!');
        });

        return panel;
    };

    // Create emoji picker
    const createPicker = (composer, wrapper) => {
        const picker = document.createElement('div');
        picker.className = 'emoji-picker';
        picker.style.display = 'none';

        emotes.forEach(emote => {
            const item = document.createElement('div');
            item.className = 'emoji-item';
            item.title = emote.name;
            item.innerHTML = `<img src="${emote.url}" alt="${emote.name}">`;

            item.addEventListener('click', async (e) => {
                e.preventDefault();
                e.stopPropagation();

                const submitBtn = composer.closest('faceplate-form')?.querySelector('button[slot="submit-button"]') ||
                                composer.querySelector('button[slot="submit-button"]');
                const wasDisabled = submitBtn?.disabled ?? false;

                if (submitBtn) submitBtn.disabled = true;

                try {
                    if (config.autoSwitchToMarkdown) {
                        await switchToMarkdown(composer);
                        await new Promise(resolve => setTimeout(resolve, 300));
                    } else {
                        await switchToMarkdown(composer);
                    }

                    const textArea = composer.shadowRoot?.querySelector('shreddit-markdown-composer textarea') ||
                                   composer.shadowRoot?.querySelector('[data-lexical-editor="true"]');

                    if (textArea) textArea.focus();
                    await new Promise(resolve => setTimeout(resolve, 50));

                    await insertEmote(emote.code, composer, wrapper);

                    if (submitBtn && !wasDisabled) {
                        setTimeout(() => submitBtn.disabled = false, 100);
                    }
                } catch (error) {
                    showStatus(wrapper, 'Error', 2000);
                    if (submitBtn && !wasDisabled) {
                        setTimeout(() => submitBtn.disabled = false, 300);
                    }
                }

                picker.style.display = 'none';
            }, true);

            picker.appendChild(item);
        });

        // Close on outside click
        document.addEventListener('click', (e) => {
            if (!picker.contains(e.target) && !wrapper.querySelector('.emoji-btn').contains(e.target)) {
                picker.style.display = 'none';
            }
        }, false);

        return picker;
    };

    // Helper to find all shadow DOM elements
    const getAllElements = (root = document) => {
        const elements = Array.from(root.querySelectorAll('*'));
        root.querySelectorAll('*').forEach(el => {
            if (el.shadowRoot) {
                elements.push(...getAllElements(el.shadowRoot));
            }
        });
        return elements;
    };

    // Switch to markdown mode
    const switchToMarkdown = (composer) => new Promise(resolve => {
        if (!composer?.shadowRoot) return resolve();

        // Try lexical editor first
        const lexicalEditor = composer.shadowRoot.querySelector('[data-lexical-editor="true"]');
        if (lexicalEditor) {
            lexicalEditor.click();
            lexicalEditor.focus();
            return setTimeout(resolve, 100);
        }

        // Try markdown composer
        const markdownComposer = composer.shadowRoot.querySelector('shreddit-markdown-composer');
        const textarea = markdownComposer?.shadowRoot?.querySelector('textarea');
        if (textarea) {
            textarea.click();
            textarea.focus();
            return setTimeout(resolve, 100);
        }

        // Try trigger button to switch modes
        const triggerBtn = composer.shadowRoot.querySelector('[data-testid="trigger-button"]');
        if (triggerBtn) {
            triggerBtn.click();
            return setTimeout(resolve, 300);
        }

        resolve();
    });

    // Auto-switch functionality for markdown mode
    const autoSwitchToMarkdown = (root = document.body) => {
        if (!config.autoSwitchToMarkdown) return;

        const rootElements = root.shadowRoot || root;

        if (!hasShownFormattingBar) {
            const formattingData = rootElements === document.body ?
                getAllElements(rootElements).filter(el =>
                    el.tagName === 'DATA' &&
                    el.getAttribute('data-key') === 'formattingBar' &&
                    el.getAttribute('data-show-formatting-bar') === 'false'
                ) :
                Array.from(rootElements.querySelectorAll('data[data-key="formattingBar"][data-show-formatting-bar="false"]'));

            if (formattingData.length) {
                const toolbarButtons = rootElements === document.body ?
                    getAllElements(rootElements).filter(el => el.tagName === 'RTE-TOOLBAR-BUTTON') :
                    Array.from(rootElements.querySelectorAll('rte-toolbar-button'));

                for (const btn of toolbarButtons) {
                    if (btn.offsetParent && btn.getAttribute('screenreadercontent') === 'Show formatting options') {
                        btn.click();
                        hasShownFormattingBar = true;
                        setTimeout(() => switchToMarkdownEditor(rootElements), 300);
                        break;
                    }
                }
            } else {
                switchToMarkdownEditor(rootElements);
            }
        }
    };

    const switchToMarkdownEditor = (root) => {
        if (hasSwitchedToMarkdown) return;

        const markdownButtons = root === document.body ?
            getAllElements(root).filter(el =>
                el.tagName === 'BUTTON' &&
                el.getAttribute('aria-label') === 'Switch to Markdown Editor'
            ) :
            Array.from(root.querySelectorAll('button[aria-label="Switch to Markdown Editor"]'));

        if (markdownButtons.length && markdownButtons[0].offsetParent) {
            markdownButtons[0].click();
            hasSwitchedToMarkdown = true;
        }
    };

    // Insert emote into composer
    const insertEmote = (code, composer, wrapper) => {
        if (!composer?.shadowRoot) return;

        // Try markdown textarea first
        const markdownComposer = composer.shadowRoot.querySelector('shreddit-markdown-composer');
        const textarea = markdownComposer?.shadowRoot?.querySelector('textarea');

        if (textarea) {
            textarea.focus();
            const startPos = textarea.selectionStart;
            const endPos = textarea.selectionEnd;
            const textBefore = textarea.value.substring(0, startPos);
            const textAfter = textarea.value.substring(endPos);

            textarea.value = textBefore + code + ' ' + textAfter;
            const newPos = startPos + code.length + 1;
            textarea.setSelectionRange(newPos, newPos);

            // Trigger events to notify Reddit
            textarea.dispatchEvent(new Event('input', {bubbles: true}));
            textarea.dispatchEvent(new Event('change', {bubbles: true}));

            showStatus(wrapper, 'Added!', 1000);
            return;
        }

        // Fallback to lexical editor
        const lexicalEditor = composer.shadowRoot.querySelector('[data-lexical-editor="true"]');
        if (lexicalEditor) {
            lexicalEditor.focus();

            try {
                // Try modern insertText command
                if (document.execCommand('insertText', false, code + ' ')) {
                    showStatus(wrapper, 'Added!', 1000);
                    return;
                }
            } catch (e) {
                // Fall back to manual insertion
            }

            // Manual insertion fallback
            const selection = window.getSelection();
            const textNode = document.createTextNode(code + ' ');

            if (selection.rangeCount) {
                const range = selection.getRangeAt(0);
                range.deleteContents();
                range.insertNode(textNode);
                range.setStartAfter(textNode);
                selection.removeAllRanges();
                selection.addRange(range);
            } else {
                lexicalEditor.appendChild(textNode);
            }

            showStatus(wrapper, 'Added!', 1000);
        }
    };

    // Initialize composers
    const initComposers = () => {
        document.querySelectorAll('shreddit-composer:not([data-emoji-picker-added="true"])').forEach(composer => {
            composer.setAttribute('data-emoji-picker-added', 'true');

            const wrapper = document.createElement('div');
            wrapper.className = 'emoji-wrapper';

            const statusDiv = document.createElement('div');
            statusDiv.className = 'emoji-status';

            wrapper.appendChild(createButton());
            wrapper.appendChild(statusDiv);
            wrapper.appendChild(createPicker(composer, wrapper));
            wrapper.appendChild(createSettingsBtn());
            wrapper.appendChild(createSettings());

            composer.parentNode?.insertBefore(wrapper, composer);
        });
    };

    // Track composers and handle auto-switching
    const trackComposers = () => {
        getAllElements(document).filter(el => el.tagName === 'SHREDDIT-COMPOSER').forEach(composer => {
            if (!addedElements.has(composer)) {
                addedElements.set(composer, true);
                switchToMarkdown(composer).then(() => {
                    setTimeout(() => {
                        if (config.autoSwitchToMarkdown) {
                            hasShownFormattingBar = false;
                            hasSwitchedToMarkdown = false;
                            autoSwitchToMarkdown(composer);
                        }
                    }, 750);
                });
            }
        });

        // Clean up removed elements
        addedElements.forEach((value, element) => {
            if (!document.contains(element)) {
                addedElements.delete(element);
            }
        });
    };

    // Auto-switch functionality (simplified)
    const enableAutoSwitch = () => {
        if (!mutationObserver) {
            mutationObserver = new MutationObserver(() => {
                autoSwitchToMarkdown();
                trackComposers();
            });
            mutationObserver.observe(document.body, {childList: true, subtree: true});
            trackComposers();
        }
    };

    const disableAutoSwitch = () => {
        if (mutationObserver) {
            mutationObserver.disconnect();
            mutationObserver = null;
            hasShownFormattingBar = false;
            hasSwitchedToMarkdown = false;
            addedElements.clear();
        }
    };

    // Setup mutation observer for new composers
    const setupObserver = () => {
        new MutationObserver(mutations => {
            const hasNewComposer = mutations.some(mutation =>
                Array.from(mutation.addedNodes).some(node =>
                    node.nodeType === Node.ELEMENT_NODE &&
                    (node.tagName === 'SHREDDIT-COMPOSER' || node.querySelector('shreddit-composer'))
                )
            );
            if (hasNewComposer) setTimeout(initComposers, 500);
        }).observe(document.body, {childList: true, subtree: true});
    };

    // Initialize
    const init = () => {
        if (config.autoSwitchToMarkdown) enableAutoSwitch();
        setTimeout(() => {
            initComposers();
            setupObserver();
        }, 1000);
        setInterval(initComposers, 3000);
    };

    if (document.readyState === 'complete') {
        init();
    } else {
        window.addEventListener('load', init);
    }
})();