заставить document.execCommand ('insertText', false, 'message') работать с draftjs? - PullRequest
0 голосов
/ 18 января 2019

Я работаю над приложением, которому нужно вставить текст в contenteditable="true" div (для точного текстового поля Draftjs).

Теперь я знаю, что Draft.js использует реагирует и что его следует использовать таким образом, но в этом случае приложение уже существует, и это стороннее электронное приложение, которое работает с ним.

Я работаю над встроенным уведомлением, отвечающим на macOS, поэтому мне нужно, чтобы этот текст ответа был вставлен в поле draftJS, однако, когда я делаю это, используя:

document.querySelector('div[contenteditable="true"]').focus();
document.execCommand('insertText', false, 'message');

выдает ошибку: error image

Я смог заставить его работать, используя:

const event = document.createEvent('TextEvent');
event.initTextEvent('textInput', true, true, window, 'message', 0, locale);

но этот API устарел и не работает должным образом, если сообщение содержит смайлики.

Есть ли способ сделать это, чтобы не вызвать ошибку? Я обнаружил, что новый API, который должен заменить initTextEvent, просто new Event() (см. docs ), но я не могу выяснить, поддерживает ли он события textInput.

Чтобы поиграть с ним, вы можете просто перейти к https://draftjs.org/ и поиграть с ним в Chrome Dev Tools.

Я был бы очень признателен за помощь, поскольку я не знаю, что делать, чтобы это работало. Кроме того, я знаю, что люди являются поклонниками jquery, но я бы предпочел нативное решение js (хотя любое решение приветствуется).

редактировать:

Обратите внимание: Я не использую реагирование, поле ввода, которое я хочу изменить (draftjs), использует реагирование, и я хочу ввести в него текст, используя нативный js.

редактировать 2:

Для всех, кто сталкивался с этой проблемой, я хотел вставить текст в текстовое поле мессенджера Facebook (в котором используется Draftjs).

Мне удалось найти рабочий обходной путь. Он использует устаревший API (event.initTextEvent), но я обнаружил, что это единственный способ, который работает, даже с Emoji. Пожалуйста, оставьте ответ, если у вас есть лучшее решение для этого. Это работает так:

async function sendReply(message: string): Promise<void> {
       const inputField = document.querySelector('[contenteditable="true"]') as HTMLElement;
       if (inputField) {
               const previousMessage = inputField.textContent;
               // Send message
               inputField.focus();
               await insertMessageText(message, inputField);
               (await elementReady('._30yy._38lh._39bl')).click();
               // Restore (possible) previous message
               if (previousMessage) {
                       insertMessageText(previousMessage, inputField);
               }
       }
}

function insertMessageText(text: string, inputField: HTMLElement): void {
       // Workaround: insert placeholder value to get execCommand working
       if (!inputField.textContent) {
               const event = document.createEvent('TextEvent');
               event.initTextEvent('textInput', true, true, window, '_', 0, '');
               inputField.dispatchEvent(event);
       }

       document.execCommand('selectAll', false, undefined);
       document.execCommand('insertText', false, text);
}

Это машинописный код, поэтому вы можете изменить его на js.

Он работает путем вставки значения заполнителя в textField с использованием event.initTextEvent, а затем замены этого текста на:

document.execCommand('selectAll', false, undefined);
document.execCommand('insertText', false, 'text');

протестировано в Chrome: версия 71.0.3578.98

...