🐛 | Fix message input

This commit is contained in:
2026-05-19 02:34:44 +03:00
parent b600aa7e07
commit ea368477c4
3 changed files with 202 additions and 14 deletions

View File

@@ -67,31 +67,75 @@ scoped.onDispose(() => removeCss());
// ── Helper: find and fill the message input ─────────────────────
function setMessageInput(text) {
// Find the Discord chat textarea
const textarea = document.querySelector(
'main [class*="channelTextArea"] textarea, ' +
'main [class*="channelTextArea"] [role="textbox"], ' +
'[class*="chat"] [class*="channelTextArea"] textarea, ' +
'[class*="chat"] [class*="channelTextArea"] [role="textbox"]'
);
// Broad selectors for Discord's chat input (textarea or contenteditable div)
const selectors = [
// Modern Discord: Slate-based contenteditable div
'[class*="channelTextArea"] div[role="textbox"][contenteditable="true"]',
'[class*="channelTextArea"] [data-slate-editor="true"]',
// Classic Discord: textarea inside channelTextArea
'[class*="channelTextArea"] textarea',
// Fallback: role="textbox" anywhere inside channelTextArea
'[class*="channelTextArea"] [role="textbox"]',
// Even broader fallbacks (no main/chat prefix)
'main [class*="channelTextArea"] textarea',
'main [class*="channelTextArea"] [role="textbox"]',
'[class*="chat"] [class*="channelTextArea"] textarea',
'[class*="chat"] [class*="channelTextArea"] [role="textbox"]',
];
let textarea = null;
for (const sel of selectors) {
textarea = document.querySelector(sel);
if (textarea) break;
}
if (!textarea) return false;
// The native textarea (or contenteditable div) inside
const nativeInput = textarea.tagName === "TEXTAREA"
? textarea
: textarea.querySelector("textarea");
// Determine the native input element
let nativeInput;
const isContentEditable =
textarea.tagName !== "TEXTAREA" &&
(textarea.isContentEditable || textarea.getAttribute("contenteditable") === "true");
if (textarea.tagName === "TEXTAREA") {
// Classic Discord: direct textarea element
nativeInput = textarea;
} else if (isContentEditable) {
// Modern Discord: Slate/contenteditable div - use it directly
nativeInput = textarea;
} else {
// Look for a nested textarea (older layout)
nativeInput = textarea.querySelector("textarea");
}
if (!nativeInput) return false;
// Set the native value
// Set the value
nativeInput.focus();
nativeInput.value = text;
if (nativeInput.tagName === "TEXTAREA") {
// Classic textarea input
nativeInput.value = text;
} else {
// ContentEditable div (Slate editor / modern Discord)
// Clear existing content and insert new text
nativeInput.textContent = "";
nativeInput.focus();
// Use execCommand as fallback for Slate-based editors
try {
document.execCommand("insertText", false, text);
} catch (_) {
// Fallback: set textContent directly
nativeInput.textContent = text;
}
}
// Dispatch an input event so React picks up the change
const nativeInputEv = new Event("input", { bubbles: true, cancelable: true });
nativeInput.dispatchEvent(nativeInputEv);
// Also dispatch on the outer element if it's a contenteditable
// Also dispatch on the outer element if it differs and is contenteditable
if (textarea !== nativeInput && textarea.isContentEditable) {
textarea.textContent = text;
textarea.dispatchEvent(new Event("input", { bubbles: true }));