1
1
Fork 0
CCNA_Autofill_Userscript/fetch.js
2024-05-23 17:43:28 +02:00

145 lines
3.5 KiB
JavaScript

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