Автоматизация создания и отправки сообщений о решении LeetCode: проблемы с манипулированием DOM, API буфера обмена и редJavascript

Форум по Javascript
Ответить
Anonymous
 Автоматизация создания и отправки сообщений о решении LeetCode: проблемы с манипулированием DOM, API буфера обмена и ред

Сообщение Anonymous »

Я создаю расширение Chrome для автоматизации создания сообщений о решениях в LeetCode после того, как решение будет принято. Цель: 1. Откройте страницу «Опубликовать решение».2. Автоматически заполняйте поле ввода «Название» пользовательской строкой.3. Заполните редактор Monaco отформатированным шаблоном решения.
Настройка
1. Среда:
• Расширение Chrome (Manifest V3) с использованием Plasmo Framework.
• Расширение включает в себя:
• Фоновый скрипт для создания вкладок и обмена сообщениями.
• Сценарий содержимого для Взаимодействие с DOM на странице «Опубликовать решение».
2. Подход:
• Фоновый сценарий открывает страницу публикации решения и отправляет сообщение сценарию содержимого с шаблоном для вставки.
• Сценарий содержимого обрабатывает манипуляции с DOM, включая:
• Ввод текста. в поле ввода.
• Копирование и вставка содержимого в редактор Monaco.
Проблемы и что мы пробовали
  • Заполнение ввода заголовка Поле
Проблема:
Поле ввода иногда обновляется частично (например, «Автоматический заголовок» становится «Томированным заголовком») или не обновляется. вообще.
Попытки:
1. Непосредственная установка значения:

Код: Выделить всё

inputElement.value = "Automated Title";
inputElement.dispatchEvent(new Event("input", { bubbles: true }));
inputElement.dispatchEvent(new Event("change", { bubbles: true }));
•Результат: иногда работает, но часто не обновляет поле должным образом или не запускает прослушиватели, которые сбрасывают значение.
2. Имитация событий нажатия клавиш. :

Код: Выделить всё

for (const char of text) {
inputElement.value += char;
inputElement.dispatchEvent(new KeyboardEvent("keydown", { key: char }));
inputElement.dispatchEvent(new KeyboardEvent("keypress", { key: char }));
inputElement.dispatchEvent(new KeyboardEvent("keyup", { key: char }));
}
•Результат: это работает лучше, но иногда приводит к неполному тексту. Похоже, что внешние прослушиватели событий или обновления DOM мешают этому процессу.
  • Копирование текста в буфер обмена и вставка:

    Код: Выделить всё

    await navigator.clipboard.writeText("Automated Title");
    const pasteEvent = new ClipboardEvent("paste", { bubbles: true });
    inputElement.dispatchEvent(pasteEvent);
    
    •Результат: API буфера обмена завершается с ошибкой NotAllowedError, если только это не вызвано взаимодействием с пользователем (например, нажатием кнопки).
  • Заполнение редактора Monaco
Проблема:
Редактор Monaco использует функцию monaco.editor.getModels()[ 0] API, чего нет доступен напрямую из сценария содержимого, поскольку сценарий выполняется в другом контексте выполнения.
Попытки:
1. Использование API Монако:

Код: Выделить всё

const model = monaco.editor.getModels()[0];
model.setValue(template);
•Результат: отлично работает в консоли браузера, но не работает в сценарии содержимого, поскольку Monaco не определен.
2.Внедрение кода в основной мир:
• Внедрил функцию с помощью chrome.scripting.executeScript:

Код: Выделить всё

chrome.scripting.executeScript({
target: { tabId: tab.id },
world: "MAIN",
func: pasteTemplateIntoPage,
args: [template],
});
•Результат: Монако не определено в основном мире из-за ограничений CSP.
  • Обработка Ограничение скорости (429 ошибок)
Проблема:
Иногда установка заголовка запускает серверные запросы LeetCode, которые приводят к ошибке 429 Too Many Requests.
Попытки:
1. Добавлены задержки между действиями.
2. Уменьшено количество ненужной отправки событий.
3. Используется устранение дребезга, чтобы избежать быстрого взаимодействия.
•Результат: ограничение скорости сохраняется, даже если действия выполняются слишком часто.
Фрагменты кода
Фоновый сценарий:

Код: Выделить всё

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === "openSubmissionPage") {
chrome.tabs.create({ url: message.url, active: true }, (tab) => {
if (tab?.id) {
chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo) {
if (tabId === tab.id && changeInfo.status === "complete") {
chrome.tabs.onUpdated.removeListener(listener);
chrome.tabs.sendMessage(tab.id, { action: "pasteTemplate", template:            message.template });
}
});
}
});
Скрипт содержимого:

Код: Выделить всё

async function typeIntoInputField(selector, text) {
const inputElement = document.querySelector(selector);
if (!inputElement) return;

inputElement.value = "";
for (const char of text) {
inputElement.value += char;
inputElement.dispatchEvent(new KeyboardEvent("keydown", { key: char }));
inputElement.dispatchEvent(new KeyboardEvent("keypress", { key: char }));
inputElement.dispatchEvent(new KeyboardEvent("keyup", { key: char }));
await new Promise((r) => setTimeout(r, 100));
}
}
В чем нам нужна помощь:
1. Как мы можем надежно установить значение поля ввода заголовка (например, «Автоматическое название»), избегая при этом частичных обновлений или сбросов?
2. Как лучше всего получить доступ к редактору Monaco и управлять им в расширении Chrome?
3. Как мы можем избежать срабатывания ограничения скорости LeetCode (429 ошибок) во время манипуляций с DOM?
4. Существуют ли другие надежные методы программного моделирования взаимодействия с пользователем (ввод текста, вставка)?
Что мы пробовали:
• Прямые манипуляции с DOM (значение, setAttribute).
• Имитация нажатий клавиш с помощью KeyboardEvent.
• Копирование в буфер обмена и вставка с помощью ClipboardEvent.
• Внедрение кода в основной мир для доступа к API Монако.
Несмотря на все эти попытки, я по-прежнему сталкиваюсь с проблемами с надежностью и совместимостью. Мы будем очень признательны за любые советы, идеи или альтернативные подходы!
Не стесняйтесь копировать и вставлять эту текстовую версию в Stack Overflow!

Подробнее здесь: https://stackoverflow.com/questions/793 ... with-dom-m
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»