diff --git a/main.user.js b/main.user.js index 2fc0123..a587b13 100644 --- a/main.user.js +++ b/main.user.js @@ -9,4 +9,164 @@ // @grant GM_log // @version 0.0.1 // @author Dominik Säume -// ==/UserScript== \ No newline at end of file +// ==/UserScript== + +const URL_STORAGE_KEY = "itexamanswers.net URL"; +let awnserData; + +console.log = console.__proto__.log; + +window.addEventListener("keydown", event => { + switch(event.key){ + case "p": + const oldAwnsersURL = GM_getValue(URL_STORAGE_KEY); + let newAwnsersURL = prompt("Please input the answer url (itexamanswers.net)", oldAwnsersURL); + GM_setValue(URL_STORAGE_KEY, newAwnsersURL); + fetchData(newAwnsersURL); + break; + + case "n": + document.getElementById("next").click(); + break; + + case "a": + awnserQuestion(); + break; + } +}) + +function awnserQuestion(){ + const question = document.querySelector(".question:not(.hidden)"); + if (!question) { + return; + } + + const questionTextDom = question.querySelector(".questionText .mattext"); + if (!questionTextDom) return; + const questionText = questionTextDom.textContent.trim(); + + const answersDom = question.querySelector("ul.coreContent"); + if (!answersDom) return; + const answers = answersDom.children; + + for (let answer of answers) { + const input = answer.querySelector("input"); + if (!input) continue; + input.checked = false; + } + + const correctAnswers = findAnswers(questionText, answers); + if (correctAnswers.length === 0) { + GM_log("no awnser") + return; + } + + for (const answer of correctAnswers) { + const input = answer.querySelector("input"); + if (!input) continue; + input.checked = true; + } +} + +function findAnswers(questionText, answers) { + if (awnserData === null) { + alert("No chapter data loaded. Maybe the fetch failed?!"); + return []; + } + + const correctAnswers = []; + for (let entry of awnserData) { + if (matchAwnser(questionText.trim(), entry.question.trim())) { + for (let availableAnswer of answers) { + for (let possibleAnswer of entry.answers) { + if (matchAwnser(availableAnswer.textContent.trim(), possibleAnswer)) { + correctAnswers.push(availableAnswer); + } + } + } + } + } + + return correctAnswers; +} + +function matchAwnser(textA, textB) { + const replaceRegex = /[^\w]/gi; + textA = textA.replace(replaceRegex, ""); + textB = textB.replace(replaceRegex, ""); + return (textA === textB); +} + +function fetchData(awnserURL = ""){ + GM_xmlhttpRequest({ + method: "GET", + url: awnserURL, + headers: { + "Content-Type": "text/html" + }, + onload: function(response) { + awnserImgs = new Map(); + const results = []; + const parser = new DOMParser(); + const virtDom = parser.parseFromString(response.responseText, "text/html"); + + let answersDom = virtDom.querySelector(".pf-content"); + if (!answersDom) { + answersDom = virtDom.querySelector(".thecontent"); + } + + let index = -1; + for (let childDom of answersDom.children) { + index++; + + if (childDom.tagName === "P" || childDom.tagName === "STRONG" ) { + + // maybe a question question + let innerDom = childDom.querySelector("strong"); + if (innerDom === null) { + if(!childDom.textContent){ + continue; + } + innerDom = childDom; + }; + + const textContent = innerDom.textContent.trim(); + const matches = textContent.match(/^[0-9]+\. (.*)$/); + if (matches !== null) { + const questionText = matches[1]; + + // most likely a question + let nextChild = answersDom.children[index + 1]; + + if (nextChild.tagName === "P"){ + nextChild = answersDom.children[index + 2]; + }; + + if (nextChild === null) continue; + + if (nextChild.tagName === "UL") { + // most likely the awnser + const answers = []; + for (let answerDom of nextChild.querySelectorAll("strong")) { + let answerText = answerDom.textContent.trim(); + if (answerText.endsWith("*")) { + answerText = answerText.substring(0, answerText.length - 1); + } + answers.push(answerText); + } + + results.push({ + question: questionText, + answers: answers + }); + } + } + + } + } + awnserData = results; + GM_log(results); + GM_log(awnserImgs); + } + }); +} \ No newline at end of file