Size
7.1 KB
Version
1.0.1
Created
Mar 18, 2026
Updated
29 days ago
1// ==UserScript==
2// @name IXL Auto Answer
3// @description Automatically answers IXL questions using AI
4// @version 1.0.1
5// @match https://*.ixl.com/*
6// @icon https://www.ixl.com/ixl-favicon.png
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 console.log('IXL Auto Answer extension loaded');
12
13 // Add a button to trigger auto-answer
14 function addAutoAnswerButton() {
15 // Check if button already exists
16 if (document.getElementById('ixl-auto-answer-btn')) {
17 return;
18 }
19
20 // Find the submit button container
21 const submitContainer = document.querySelector('.yui3-widget-ft');
22 if (!submitContainer) {
23 console.log('Submit container not found, retrying...');
24 setTimeout(addAutoAnswerButton, 1000);
25 return;
26 }
27
28 // Create auto-answer button
29 const autoAnswerBtn = document.createElement('button');
30 autoAnswerBtn.id = 'ixl-auto-answer-btn';
31 autoAnswerBtn.textContent = 'Auto Answer';
32 autoAnswerBtn.className = 'crisp-button';
33 autoAnswerBtn.style.marginRight = '10px';
34 autoAnswerBtn.style.backgroundColor = '#4CAF50';
35 autoAnswerBtn.style.color = 'white';
36
37 // Insert before submit button
38 submitContainer.insertBefore(autoAnswerBtn, submitContainer.firstChild);
39
40 // Add click handler
41 autoAnswerBtn.addEventListener('click', async () => {
42 await autoAnswerQuestion();
43 });
44
45 console.log('Auto Answer button added');
46 }
47
48 // Main function to automatically answer the question
49 async function autoAnswerQuestion() {
50 try {
51 console.log('Starting auto-answer process...');
52
53 // Get the question instruction
54 const instructionElement = document.querySelector('.secHdr .rich-text');
55 const instruction = instructionElement ? instructionElement.textContent.trim() : '';
56
57 // Get all the sentence parts
58 const sentenceParts = Array.from(document.querySelectorAll('.select-edit-text-clickable .rich-text')).map(el => el.textContent.trim());
59 const fullSentence = sentenceParts.join(' ');
60
61 console.log('Instruction:', instruction);
62 console.log('Sentence:', fullSentence);
63
64 if (!instruction || !fullSentence) {
65 console.error('Could not extract question data');
66 alert('Could not extract question data. Please try again.');
67 return;
68 }
69
70 // Show loading indicator
71 const autoAnswerBtn = document.getElementById('ixl-auto-answer-btn');
72 const originalText = autoAnswerBtn.textContent;
73 autoAnswerBtn.textContent = 'Analyzing...';
74 autoAnswerBtn.disabled = true;
75
76 // Use AI to analyze and answer the question
77 const prompt = `${instruction}
78
79Sentence: "${fullSentence}"
80
81Please analyze this sentence and provide:
821. The incorrect word that needs to be fixed
832. The correct version of that word
84
85Return your answer in the following format.`;
86
87 const aiResponse = await RM.aiCall(prompt, {
88 type: "json_schema",
89 json_schema: {
90 name: "grammar_correction",
91 schema: {
92 type: "object",
93 properties: {
94 incorrectWord: { type: "string" },
95 correctWord: { type: "string" },
96 explanation: { type: "string" }
97 },
98 required: ["incorrectWord", "correctWord"]
99 }
100 }
101 });
102
103 console.log('AI Response:', aiResponse);
104
105 // Find and click the incorrect word
106 const wordElements = document.querySelectorAll('.select-edit-text-clickable');
107 let foundWord = false;
108
109 for (const element of wordElements) {
110 const wordText = element.textContent.trim();
111 if (wordText.toLowerCase() === aiResponse.incorrectWord.toLowerCase()) {
112 console.log('Found incorrect word:', wordText);
113 element.click();
114 foundWord = true;
115
116 // Wait for input field to appear
117 await new Promise(resolve => setTimeout(resolve, 500));
118
119 // Find the input field and enter the correct word
120 const inputField = document.querySelector('input[type="text"].select-edit-input');
121 if (inputField) {
122 inputField.value = aiResponse.correctWord;
123 inputField.dispatchEvent(new Event('input', { bubbles: true }));
124 inputField.dispatchEvent(new Event('change', { bubbles: true }));
125 console.log('Entered correct word:', aiResponse.correctWord);
126
127 // Wait a bit before submitting
128 await new Promise(resolve => setTimeout(resolve, 500));
129
130 // Click submit button
131 const submitBtn = document.querySelector('.yui3-widget-ft button.crisp-button:not(#ixl-auto-answer-btn)');
132 if (submitBtn) {
133 submitBtn.click();
134 console.log('Answer submitted!');
135 }
136 } else {
137 console.error('Input field not found');
138 alert('Could not find input field to enter answer');
139 }
140
141 break;
142 }
143 }
144
145 if (!foundWord) {
146 console.error('Could not find the incorrect word:', aiResponse.incorrectWord);
147 alert(`Could not find the word "${aiResponse.incorrectWord}" in the sentence`);
148 }
149
150 // Restore button
151 autoAnswerBtn.textContent = originalText;
152 autoAnswerBtn.disabled = false;
153
154 } catch (error) {
155 console.error('Error in auto-answer:', error);
156 alert('Error: ' + error.message);
157
158 // Restore button
159 const autoAnswerBtn = document.getElementById('ixl-auto-answer-btn');
160 if (autoAnswerBtn) {
161 autoAnswerBtn.textContent = 'Auto Answer';
162 autoAnswerBtn.disabled = false;
163 }
164 }
165 }
166
167 // Initialize when page is ready
168 function init() {
169 console.log('Initializing IXL Auto Answer...');
170
171 // Wait for page to be fully loaded
172 if (document.readyState === 'loading') {
173 document.addEventListener('DOMContentLoaded', addAutoAnswerButton);
174 } else {
175 addAutoAnswerButton();
176 }
177
178 // Also observe for dynamic content changes
179 const observer = new MutationObserver(() => {
180 addAutoAnswerButton();
181 });
182
183 observer.observe(document.body, {
184 childList: true,
185 subtree: true
186 });
187 }
188
189 // Start the extension
190 init();
191})();