Skip to content

Instantly share code, notes, and snippets.

@nmanumr
Created June 2, 2019 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nmanumr/6cdd6d86a2425c5acbecd3d44da755c1 to your computer and use it in GitHub Desktop.
Save nmanumr/6cdd6d86a2425c5acbecd3d44da755c1 to your computer and use it in GitHub Desktop.
class McqParser {
getQuestionNode(doc) {
return doc.querySelector('.question_box>h3>p');
}
getOption(labelEl) {
return new McqChoice(
labelEl.innerHTML,
labelEl.title
);
}
getOptions(doc) {
var options = [];
var labels = doc.querySelectorAll('.question_box>label');
labels.forEach((labelEl) => {
options.push(this.getOption(labelEl));
})
return options;
}
parse(doc) {
return new MCQ(
this.getQuestionNode(doc),
this.getOptions(doc)
)
}
}
class MCQ {
constructor(text, choices, ans) {
this.text = text;
this.choices = choices;
this.ans = ans;
}
static loadFromObj(obj) {
var text;
if(typeof obj.text == 'string'){
text = document.createElement('p');
text.innerText = text;
}
else
text = obj.text;
return new MCQ(text, obj.choices, obj.ans);
}
getJSON() {
var options = this.choices.map((opt) => opt.getJSON())
return {
text: this.text.innerText.trim(),
choices: options,
ans: this.ans
}
}
existsIn(qDict) {
for (var qId in qDict) {
if (qDict[qId].text == this.text.innerText.trim())
return MCQ.loadFromObj(qDict[qId]);
}
}
mark(id) {
document.querySelector(`[value='${id}']`).click();
}
getHash() {
return this.text.innerText.trim().hashCode();
}
setAns(id) {
this.ans = id;
}
updateAnsFromText(text){
for(var choice of this.choices){
if(choice.text == text){
this.ans = choice.id;
return;
}
}
}
}
class McqChoice {
constructor(text, id) {
this.text = text;
this.id = id;
}
getJSON() {
return {
text: this.text.trim(),
id: this.id
}
}
}
class TabularParser {
getNthCol(row, n) {
return row.querySelector(`td:nth-child(${n})`);
}
getNthColText(row, n) {
return this.getNthCol(row, n).innerText;
}
parse(doc) {
var data = [];
var rows = doc.querySelectorAll(`.${this.tableContainerClass}>table>tbody>tr`);
rows.forEach((row) => {
if (!row.innerText.match(/No data available/i))
data.push(this.buildObj(row));
})
return data;
}
}
class QuizDetailParser extends TabularParser {
constructor() {
super();
this.tableContainerClass = "allowance_table";
}
buildObj(row) {
return new QuizDetail(
parseInt(this.getNthColText(row, 1)),
this.getNthCol(row, 3).children[0].cloneNode(true),
this.getNthCol(row, 4).children[0].cloneNode(true),
this.getNthCol(row, 5).children[0].cloneNode(true),
)
}
}
class QuizDetail {
constructor(index, question, crctAns, wrngAns) {
this.index = index;
this.text = question;
this.correctAns = crctAns;
this.wrongAns = wrngAns;
}
getJSON() {
return {
text: this.text.innerText.trim(),
correctAns: this.correctAns.innerText.trim(),
wrngAns: this.wrongAns.innerText.trim()
}
}
}
function detailPageHandler() {
var qDict = JSON.parse(localStorage['qDict'] || '{}');
var parser = new QuizDetailParser();
var questions = parser.parse(document);
for(var question of questions){
var mcq = MCQ.loadFromObj(question);
var savedMcq = mcq.existsIn(qDict);
if (savedMcq) {
savedMcq.updateAnsFromText(question.correctAns)
console.log(`UPDATED: ${question.text.innerText}`);
}
}
}
function McqPageHandler() {
var qDict = JSON.parse(localStorage['qDict'] || '{}');
var parser = new McqParser();
var parsedMcq = parser.parse(document);
var savedMcq = parsedMcq.existsIn(qDict)
if (savedMcq) {
parsedMcq.mark(savedMcq.ans);
console.log("Question found");
console.log("Known correct option marked");
}
else {
console.log("Question not found");
document.querySelector(`.submit_btn`).setAttribute('onclick', '')
document.querySelectorAll("[name='quiz_option']")
.forEach((el) => {
el.addEventListener("click", (e) => {
parsedMcq.setAns(e.target.value);
});
});
document.querySelector(`.submit_btn`)
.addEventListener("click", () => {
qDict[parsedMcq.getHash()] = parsedMcq.getJSON();
localStorage['qDict'] = JSON.stringify(qDict);
document.forms[0].submit();
})
}
}
var handlers = {
"GetAttemptedQuizDetails": detailPageHandler,
"PopulateSingleQuiz": McqPageHandler,
}
function main() {
for (var handler in handlers) {
var re = new RegExp(handler, "i");
if (re.exec(window.location.pathname)) {
handlers[handler]();
}
}
}
String.prototype.hashCode = function () {
var hash = 0, i, chr;
if (this.length === 0) return hash;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment