Das Setup
1. Umgebung:
• Chrome-Erweiterung (Manifest V3) mit Plasmo Framework.
• Die Erweiterung enthält:
• Ein Hintergrundskript für die Tab-Erstellung und Nachrichtenübermittlung.
• Ein Inhaltsskript für DOM-Interaktion auf der Seite „Lösung veröffentlichen“.
2. Ansatz:
• Das Hintergrundskript öffnet die Lösungsbeitragsseite und sendet eine Nachricht mit der einzufügenden Vorlage an das Inhaltsskript.
• Das Inhaltsskript übernimmt die DOM-Manipulation, einschließlich:
• Eingeben von Text in das Eingabefeld.
• Kopieren und Einfügen von Inhalten in den Monaco-Editor.
Herausforderungen und was wir versucht haben
- Das Titeleingabefeld füllen
Das Eingabefeld wird manchmal teilweise aktualisiert (z. B. wird „Automatisierter Titel“ zu „tomierter Titel“) oder überhaupt nicht aktualisiert.
Versuche:
1. Wert direkt festlegen:
Code: Select all
inputElement.value = "Automated Title";
inputElement.dispatchEvent(new Event("input", { bubbles: true }));
inputElement.dispatchEvent(new Event("change", { bubbles: true }));
2. Tastendruckereignisse simulieren :
Code: Select all
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 }));
}
- Text in die Zwischenablage kopieren und einfügen:
Code: Select all
await navigator.clipboard.writeText("Automated Title");
const pasteEvent = new ClipboardEvent("paste", { bubbles: true });
inputElement.dispatchEvent(pasteEvent);
- Auffüllen des Monaco-Editors
Der Monaco-Editor verlässt sich auf seine monaco.editor.getModels()[ 0] API, auf die nicht direkt zugegriffen werden kann das Inhaltsskript, da das Skript in einem anderen Ausführungskontext ausgeführt wird.
Versuche:
1. Verwenden der Monaco-API:
Code: Select all
const model = monaco.editor.getModels()[0];
model.setValue(template);
2. Code in die Hauptwelt einfügen:
• Eine Funktion mit chrome.scripting.executeScript eingefügt:
Code: Select all
chrome.scripting.executeScript({
target: { tabId: tab.id },
world: "MAIN",
func: pasteTemplateIntoPage,
args: [template],
});
- Handhabung Ratenbegrenzung (429 Fehler)
Gelegentlich löst das Festlegen des Titels LeetCodes Backend-Anfragen aus, die zu 429 Too Many Requests führen.
Versuche:
1. Verzögerungen zwischen Aktionen hinzugefügt.
2. Reduzierte unnötige Ereignisauslösung.
3. Entprellen wurde verwendet, um schnelle Interaktionen zu vermeiden.
•Ergebnis: Die Ratenbegrenzung bleibt bestehen, wenn Aktionen zu häufig sind.
Codeausschnitte
Hintergrundskript:
Code: Select all
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 });
}
});
}
});
Code: Select all
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. Wie können wir den Wert des Titeleingabefelds zuverlässig festlegen (z. B. „Automatisierter Titel“) und gleichzeitig Teilaktualisierungen oder Zurücksetzungen vermeiden?
2. Wie kann ich in einer Chrome-Erweiterung am besten auf den Monaco-Editor zugreifen und ihn bearbeiten?
3. Wie können wir vermeiden, dass die Geschwindigkeitsbegrenzung von LeetCode (429 Fehler) während der DOM-Manipulation ausgelöst wird?
4. Gibt es andere robuste Methoden, um Benutzerinteraktionen (Eingabe, Einfügen) programmgesteuert zu simulieren?
Was wir versucht haben:
• Direkte DOM-Manipulation (Wert, setAttribute).
• Simulieren von Tastenanschlägen mit KeyboardEvent.
• Kopieren in die Zwischenablage und Einfügen mit ClipboardEvent.
• Einfügen von Code in die Hauptwelt, um auf die Monaco-API zuzugreifen.
Trotz allem diese Trotz aller Versuche habe ich immer noch Probleme mit der Zuverlässigkeit und Kompatibilität. Für Ratschläge, Einblicke oder alternative Ansätze wäre ich sehr dankbar!