Inserting text on Zendesks CK Editor via JS (Chrome Addon) not working

So I made a Firefox Addon for inserting templates into text fields (for Customer Support agents like me).

It works flawlessly in Firefox (manifest v2). But in Chrome (v3) it is not working at all. I have already such a long code with all possible solutions I could find. And it is not working.

My Chrome code for inserting the code from the template storage:

if (!window.insertTemplateListenerAdded) {
    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
        if (message.action === 'ping') {
            sendResponse({ status: 'pong' });
        } else if (message.action === 'insertTemplate') {
            console.log('Inserting template:', message.template);
            insertTemplate(message.template);
        }
    });
    window.insertTemplateListenerAdded = true;
}

function simulateTyping(element, text) {
    console.log('Simulating typing for element:', element);
    const event = new InputEvent('input', {
        bubbles: true,
        cancelable: true,
        inputType: 'insertText',
        data: text
    });
    
    if (element.isContentEditable) {
        // For contenteditable elements
        const range = document.createRange();
        range.selectNodeContents(element);
        range.collapse(false);
        const selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
        
        document.execCommand('insertText', false, text);
    } else {
        // For input and textarea elements
        const start = element.selectionStart || 0;
        const end = element.selectionEnd || 0;
        element.value = element.value.slice(0, start) + text + element.value.slice(end);
        element.selectionStart = element.selectionEnd = start + text.length;
    }
    
    element.dispatchEvent(event);
    console.log('Typing simulation completed');
}

function insertTemplate(template) {
    console.log('Attempting to insert template');
    setTimeout(() => {
        const activeElement = document.activeElement;
        
        if (activeElement) {
            console.log('Active element found:', activeElement);
            if (activeElement.classList.contains('cke_editable') || activeElement.contentEditable === 'true') {
                console.log('CKEditor or contenteditable element detected');
                simulateTyping(activeElement, template);
            } else if (activeElement.tagName === 'TEXTAREA' || (activeElement.tagName === 'INPUT' && activeElement.type === 'text')) {
                console.log('Textarea or text input detected');
                simulateTyping(activeElement, template);
            } else {
                console.log('Unsupported active element, checking iframes');
                const iframeActiveElement = getActiveElementInIframe();
                if (iframeActiveElement) {
                    console.log('Active element found in iframe');
                    simulateTyping(iframeActiveElement, template);
                } else {
                    console.log('No suitable element found, copying to clipboard');
                    copyToClipboard(template);
                }
            }
        } else {
            console.log('No active element found, copying to clipboard');
            copyToClipboard(template);
        }
    }, 100); 
}

function getActiveElementInIframe() {
    const iframes = document.querySelectorAll('iframe');
    for (let iframe of iframes) {
        try {
            const doc = iframe.contentDocument || iframe.contentWindow.document;
            const activeElement = doc.activeElement;
            if (activeElement && (activeElement.tagName === 'TEXTAREA' || 
                (activeElement.tagName === 'INPUT' && activeElement.type === 'text') || 
                activeElement.isContentEditable || 
                activeElement.classList.contains('cke_editable'))) {
                return activeElement;
            }
        } catch (e) {
            console.error('Fehler beim Zugriff auf iframe:', e);
        }
    }
    return null;
}

function copyToClipboard(text) {
    const textArea = document.createElement('textarea');
    textArea.value = text;
    document.body.appendChild(textArea);
    textArea.select();
    document.execCommand('copy');
    document.body.removeChild(textArea);
    alert('Template copied to clipboard. Please paste it manually.');
}

// MutationObserver
const observer = new MutationObserver((mutations) => {
    for (let mutation of mutations) {
        if (mutation.type === 'childList') {
            const addedNodes = mutation.addedNodes;
            for (let node of addedNodes) {
                if (node.nodeType === Node.ELEMENT_NODE) {
                    if (node.classList && node.classList.contains('cke_editable')) {
                        console.log('CKEditor element found:', node);
                        // Hier können Sie zusätzliche Logik für den gefundenen CKEditor implementieren
                    }
                    // Suche auch in Kindelementen
                    const ckeEditables = node.querySelectorAll('.cke_editable');
                    if (ckeEditables.length > 0) {
                        console.log('CKEditor elements found in added node:', ckeEditables);
                        // Hier können Sie zusätzliche Logik für die gefundenen CKEditor-Elemente implementieren
                    }
                }
            }
        }
    }
});

observer.observe(document.body, { childList: true, subtree: true });

// Initialer Scan nach CKEditor-Elementen
console.log('Scanning for existing CKEditor elements');
const existingCkeEditables = document.querySelectorAll('.cke_editable');
if (existingCkeEditables.length > 0) {
    console.log('Existing CKEditor elements found:', existingCkeEditables);
    
}

This is my much simpler Firefox code that works for Firefox only:

function insertTextInInput(element, text) {
    const start = element.selectionStart;
    const end = element.selectionEnd;
    element.value = element.value.slice(0, start) + text + element.value.slice(end);
    element.selectionStart = element.selectionEnd = start + text.length;
}

function insertTextInContentEditable(element, text) {
    const selection = window.getSelection();
    const range = selection.getRangeAt(0);
    range.deleteContents();
    const textNode = document.createTextNode(text);
    range.insertNode(textNode);
    range.setStartAfter(textNode);
    selection.removeAllRanges();
    selection.addRange(range);
}

function insertTemplate(template) {
    const activeElement = document.activeElement;
    if (activeElement && (activeElement.tagName === 'TEXTAREA' || (activeElement.tagName === 'INPUT' && activeElement.type === 'text'))) {
        insertTextInInput(activeElement, template);
    } else if (activeElement && activeElement.isContentEditable) {
        insertTextInContentEditable(activeElement, template);
    } else {
        const textArea = document.createElement('textarea');
        textArea.value = template;
        document.body.appendChild(textArea);
        textArea.select();
        document.execCommand('copy');
        document.body.removeChild(textArea);
        alert('Template copied to clipboard. Please paste it manually.');
    }
}

// Funktion zum Abrufen des aktiven Elements innerhalb von iframes
function getActiveElementInIframe() {
    for (let i = 0; i < window.frames.length; i++) {
        try {
            const activeElement = window.frames[i].document.activeElement;
            if (activeElement && (activeElement.tagName === 'TEXTAREA' || (activeElement.tagName === 'INPUT' && activeElement.type === 'text'))) {
                return activeElement;
            }
        } catch (e) {
            continue; // Skip if cross-origin restrictions prevent access
        }
    }
    return null;
}

// MutationObserver zur Überwachung von Änderungen im DOM
if (typeof observer === 'undefined') {
    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            if (mutation.type === 'childList') {
                console.log('DOM change detected: ', mutation);
            }
        });
    });

    observer.observe(document.body, { childList: true, subtree: true });
}

I’ve tried all possible solutions that I could find. It is already super redundant code for every possible situation/editor/textfield type. But nothing works.

This is the HTML for the text editor / text field (maybe it helps):

<div class="ck ck-content ck-editor__editable ck-rounded-corners ck-editor__editable_inline ck-blurred" lang="en-US" dir="auto" role="textbox" aria-label="Public reply composer" contenteditable="true" data-test-id="omnicomposer-rich-text-ckeditor"><p><br data-cke-filler="true"></p></div>

Zendesk uses CK editor. And as said, with my Firefox version it works. But not with Chrome. It’s driving me nuts.

I beg you to help me.

Before I forgot I use Linux (Mint) and Chrome is installed via Flathub – if that makes any difference, which I somehow doubt, at least I could not find anything online.