1
1
Fork 0

Setup QS
All checks were successful
Linting / Javadoc (push) Successful in 4s

This commit is contained in:
Dominik Säume 2024-05-23 19:18:48 +02:00
parent 69fb65deb7
commit 9c0c80902e
Signed by: SZUT-Dominik
GPG key ID: 67D15BB250B41E7C
7 changed files with 156 additions and 113 deletions

18
.gitea/workflows/lint.yml Normal file
View file

@ -0,0 +1,18 @@
name: "Linting"
on:
push:
branches:
- main
jobs:
javadoc:
name: "Javadoc"
runs-on: "ubuntu-latest"
container:
image: "git.euph.dev/actions/runner-js-latest:latest"
steps:
- name: "Checkout"
uses: "https://git.euph.dev/actions/checkout@v3"
- name: "Prettier"
run: npm_config_yes=true npx prettier src/ types/ --check --log-level=error

10
.prettierrc.json Normal file
View file

@ -0,0 +1,10 @@
{
"useTabs": false,
"tabWidth": 4,
"arrowParens": "avoid",
"bracketSameLine": false,
"singleQuote": true,
"semi": true,
"trailingComma": "none",
"endOfLine": "lf"
}

2
Makefile Normal file
View file

@ -0,0 +1,2 @@
lint:
@npx prettier src/ types/ --write

View file

@ -3,22 +3,22 @@
* @param {Array<Answer>} answerData * @param {Array<Answer>} answerData
* @returns * @returns
*/ */
function answerQuestion(answerData){ function answerQuestion(answerData) {
const question = document.querySelector(".question:not(.hidden)"); const question = document.querySelector('.question:not(.hidden)');
if (!question) { if (!question) {
return; return;
} }
const questionTextDom = question.querySelector(".questionText .mattext"); const questionTextDom = question.querySelector('.questionText .mattext');
if (!questionTextDom) return; if (!questionTextDom) return;
const questionText = questionTextDom.textContent.trim(); const questionText = questionTextDom.textContent.trim();
const answersDom = question.querySelector("ul.coreContent"); const answersDom = question.querySelector('ul.coreContent');
if (!answersDom) return; if (!answersDom) return;
const answers = answersDom.children; const answers = answersDom.children;
for (let answer of Array.from(answers)) { for (let answer of Array.from(answers)) {
const input = answer.querySelector("input"); const input = answer.querySelector('input');
if (!input) continue; if (!input) continue;
input.checked = false; input.checked = false;
} }
@ -29,7 +29,7 @@ function answerQuestion(answerData){
} }
for (const answer of correctAnswers) { for (const answer of correctAnswers) {
const input = answer.querySelector("input"); const input = answer.querySelector('input');
if (!input) continue; if (!input) continue;
input.checked = true; input.checked = true;
} }
@ -51,7 +51,12 @@ function findAnswers(answerData, questionText, answers) {
if (matchAnswer(questionText.trim(), entry.question.trim())) { if (matchAnswer(questionText.trim(), entry.question.trim())) {
for (let availableAnswer of answers) { for (let availableAnswer of answers) {
for (let possibleAnswer of entry.answers) { for (let possibleAnswer of entry.answers) {
if (matchAnswer(availableAnswer.textContent.trim(), possibleAnswer)) { if (
matchAnswer(
availableAnswer.textContent.trim(),
possibleAnswer
)
) {
correctAnswers.push(availableAnswer); correctAnswers.push(availableAnswer);
} }
} }
@ -64,9 +69,9 @@ function findAnswers(answerData, questionText, answers) {
function matchAnswer(textA, textB) { function matchAnswer(textA, textB) {
const replaceRegex = /[^\w]/gi; const replaceRegex = /[^\w]/gi;
textA = textA.replace(replaceRegex, ""); textA = textA.replace(replaceRegex, '');
textB = textB.replace(replaceRegex, ""); textB = textB.replace(replaceRegex, '');
return (textA === textB); return textA === textB;
} }
window.answerQuestion = answerQuestion; window.answerQuestion = answerQuestion;

View file

@ -5,22 +5,22 @@ const QUESTION_REGEX = /^[0-9]+\. (.*)$/;
* @param {string} [answerURL=""] - The URL to fetch answers from. * @param {string} [answerURL=""] - The URL to fetch answers from.
* @returns {Promise<Array<Answer>>} A Promise that resolves with the fetched answers. * @returns {Promise<Array<Answer>>} A Promise that resolves with the fetched answers.
*/ */
function fetchAnswers(answerURL = "") { function fetchAnswers(answerURL = '') {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
GM_xmlhttpRequest({ GM_xmlhttpRequest({
method: "GET", method: 'GET',
url: answerURL, url: answerURL,
headers: { headers: {
"Content-Type": "text/html", 'Content-Type': 'text/html'
}, },
onload: function (response) { onload: function (response) {
parseAnswers(response, resolve); parseAnswers(response, resolve);
}, },
onerror: function (error) { onerror: function (error) {
reject(error); reject(error);
}, }
});
}); });
});
} }
/** /**
@ -29,19 +29,19 @@ function fetchAnswers(answerURL = "") {
* @param {(value: Answer[] | PromiseLike<Answer[]>) => void} resolve * @param {(value: Answer[] | PromiseLike<Answer[]>) => void} resolve
*/ */
function parseAnswers(response, resolve) { function parseAnswers(response, resolve) {
const results = []; const results = [];
const allAnswersElement = getAllAnswersElement(response); const allAnswersElement = getAllAnswersElement(response);
let index = -1; let index = -1;
for (let child of Array.from(allAnswersElement.children)) { for (let child of Array.from(allAnswersElement.children)) {
index++; index++;
const result = parseAnswerElement(index, child, allAnswersElement); const result = parseAnswerElement(index, child, allAnswersElement);
if (result != undefined) { if (result != undefined) {
results.push(result); results.push(result);
}
} }
}
resolve(results); resolve(results);
} }
/** /**
@ -49,14 +49,17 @@ function parseAnswers(response, resolve) {
* @returns {Element} * @returns {Element}
*/ */
function getAllAnswersElement(response) { function getAllAnswersElement(response) {
const parser = new DOMParser(); const parser = new DOMParser();
const virtualDOM = parser.parseFromString(response.responseText, "text/html"); const virtualDOM = parser.parseFromString(
response.responseText,
'text/html'
);
let answersElement = virtualDOM.querySelector(".pf-content"); let answersElement = virtualDOM.querySelector('.pf-content');
if (!answersElement) { if (!answersElement) {
answersElement = virtualDOM.querySelector(".thecontent"); answersElement = virtualDOM.querySelector('.thecontent');
} }
return answersElement; return answersElement;
} }
/** /**
@ -66,38 +69,38 @@ function getAllAnswersElement(response) {
* @returns {Answer} * @returns {Answer}
*/ */
function parseAnswerElement(index, element, allAnswersElement) { function parseAnswerElement(index, element, allAnswersElement) {
// Check for Possible Tags // Check for Possible Tags
if ( if (
!(element.tagName === "P" || element.tagName === "STRONG") || !(element.tagName === 'P' || element.tagName === 'STRONG') ||
!element.innerHTML !element.innerHTML
) { ) {
return; return;
}
// Get Question Element
/** @type {Element} */
let questionElement = element.querySelector("strong");
if (questionElement === null) {
if (!element.textContent) {
return;
} }
questionElement = element;
}
// Get Question // Get Question Element
const questionText = parseQuestion(questionElement); /** @type {Element} */
if (questionText === null) { let questionElement = element.querySelector('strong');
return; if (questionElement === null) {
} if (!element.textContent) {
return;
}
questionElement = element;
}
// Get Awsners // Get Question
const answersElement = getAnswersElement(index, allAnswersElement); const questionText = parseQuestion(questionElement);
if (answersElement === null || answersElement.tagName !== "UL") return; if (questionText === null) {
return;
}
return { // Get Awsners
question: questionText, const answersElement = getAnswersElement(index, allAnswersElement);
answers: getAnswers(answersElement), if (answersElement === null || answersElement.tagName !== 'UL') return;
};
return {
question: questionText,
answers: getAnswers(answersElement)
};
} }
/** /**
@ -105,9 +108,9 @@ function parseAnswerElement(index, element, allAnswersElement) {
* @returns {String} * @returns {String}
*/ */
function parseQuestion(questionElement) { function parseQuestion(questionElement) {
const textContent = questionElement.textContent.trim(); const textContent = questionElement.textContent.trim();
const matches = textContent.match(QUESTION_REGEX); const matches = textContent.match(QUESTION_REGEX);
return matches !== null ? matches[1] : null; return matches !== null ? matches[1] : null;
} }
/** /**
@ -116,12 +119,12 @@ function parseQuestion(questionElement) {
* @returns {Element} * @returns {Element}
*/ */
function getAnswersElement(index, allAnswersElement) { function getAnswersElement(index, allAnswersElement) {
let answersElement = allAnswersElement.children[index + 1]; let answersElement = allAnswersElement.children[index + 1];
if (answersElement.tagName === "P") { if (answersElement.tagName === 'P') {
answersElement = allAnswersElement.children[index + 2]; answersElement = allAnswersElement.children[index + 2];
} }
return answersElement; return answersElement;
} }
/** /**
@ -129,16 +132,18 @@ function getAnswersElement(index, allAnswersElement) {
* @returns {Array<string>} * @returns {Array<string>}
*/ */
function getAnswers(answersElement) { function getAnswers(answersElement) {
const answers = []; const answers = [];
for (let answerDom of Array.from(answersElement.querySelectorAll("strong"))) { for (let answerDom of Array.from(
let answerText = answerDom.textContent.trim(); answersElement.querySelectorAll('strong')
if (answerText.endsWith("*")) { )) {
answerText = answerText.substring(0, answerText.length - 1); let answerText = answerDom.textContent.trim();
if (answerText.endsWith('*')) {
answerText = answerText.substring(0, answerText.length - 1);
}
answers.push(answerText);
} }
answers.push(answerText);
}
return answers; return answers;
} }
window.fetchAnswers = fetchAnswers; window.fetchAnswers = fetchAnswers;

View file

@ -14,25 +14,28 @@
// @author Dominik Säume // @author Dominik Säume
// ==/UserScript== // ==/UserScript==
const URL_STORAGE_KEY = "itexamanswers.net URL"; const URL_STORAGE_KEY = 'itexamanswers.net URL';
/** @type {Array<Answer>} */ /** @type {Array<Answer>} */
let answerData; let answerData;
window.addEventListener("keydown", async (event) => { window.addEventListener('keydown', async event => {
switch(event.key){ switch (event.key) {
case "p": case 'p':
const oldAnswersURL = GM_getValue(URL_STORAGE_KEY); const oldAnswersURL = GM_getValue(URL_STORAGE_KEY);
const newAnswersURL = prompt("Please input the answer url (itexamanswers.net)", oldAnswersURL); const newAnswersURL = prompt(
GM_setValue(URL_STORAGE_KEY, newAnswersURL); 'Please input the answer url (itexamanswers.net)',
answerData = await window.fetchAnswers(newAnswersURL); oldAnswersURL
break; );
GM_setValue(URL_STORAGE_KEY, newAnswersURL);
answerData = await window.fetchAnswers(newAnswersURL);
break;
case "n": case 'n':
document.getElementById("next").click(); document.getElementById('next').click();
break; break;
case "a": case 'a':
window.answerQuestion(answerData); window.answerQuestion(answerData);
break; break;
} }
}); });

View file

@ -3,5 +3,5 @@
* @returns {string} * @returns {string}
*/ */
function GM_getValue(storageKey) { function GM_getValue(storageKey) {
return ""; return '';
} }