Created
June 2, 2019 20:40
-
-
Save nmanumr/6cdd6d86a2425c5acbecd3d44da755c1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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