Настройка
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 }));
}
- Копирование текста в буфер обмена и вставка:
•Результат: API буфера обмена завершается с ошибкой NotAllowedError, если только это не вызвано взаимодействием с пользователем (например, нажатием кнопки).Код: Выделить всё
await navigator.clipboard.writeText("Automated Title"); const pasteEvent = new ClipboardEvent("paste", { bubbles: true }); inputElement.dispatchEvent(pasteEvent); - Заполнение редактора Monaco
Редактор Monaco использует функцию monaco.editor.getModels()[ 0] API, чего нет доступен напрямую из сценария содержимого, поскольку сценарий выполняется в другом контексте выполнения.
Попытки:
1. Использование API Монако:
Код: Выделить всё
const model = monaco.editor.getModels()[0];
model.setValue(template);
2.Внедрение кода в основной мир:
• Внедрил функцию с помощью chrome.scripting.executeScript:
Код: Выделить всё
chrome.scripting.executeScript({
target: { tabId: tab.id },
world: "MAIN",
func: pasteTemplateIntoPage,
args: [template],
});
- Обработка Ограничение скорости (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
Мобильная версия