Moved string utils to class

This commit is contained in:
YourFriendlyNeighborhoodDealer 2019-03-15 10:14:38 +01:00
parent 580f9d9b9c
commit be3c532d3c

226
main.js
View file

@ -42,6 +42,87 @@ const minResultMatchPercent = 99; /* Minimum ammount to consider that two questi
const lengthDiffMultiplier = 10; /* Percent minus for length difference */ const lengthDiffMultiplier = 10; /* Percent minus for length difference */
//: Class descriptions {{{ //: Class descriptions {{{
class StringUtils {
SimplifyQuery(q) {
var result = q.replace(/\n/g, " ").replace(/\s/g, ' ');
return this.RemoveUnnecesarySpaces(result);
}
ShortenString(toShorten, ammount) {
var result = "";
var i = 0;
while (i < toShorten.length && i < ammount) {
result += toShorten[i];
i++;
}
return result;
}
ReplaceCharsWithSpace(val, char) {
assert(val);
assert(char);
toremove = this.NormalizeSpaces(val);
var regex = new RegExp(char, "g");
toremove.replace(regex, " ");
return this.RemoveUnnecesarySpaces(toremove);
}
// removes whitespace from begining and and, and replaces multiple spaces with one space
RemoveUnnecesarySpaces(toremove) {
toremove = this.NormalizeSpaces(toremove);
while (toremove.includes(" ")) // while the text includes double spaces replaces all of them with a single one
{
toremove = toremove.replace(/ /g, " ");
}
return toremove.trim();
}
// simplifies a string for easier comparison
SimplifyStringForComparison(value) {
value = this.RemoveUnnecesarySpaces(value).toLowerCase();
var removableChars = [",", ".", ":", "!"];
for (var i = 0; i < removableChars.length; i++) {
var regex = new RegExp(removableChars[i], "g");
value.replace(regex, "");
}
return value;
}
// if the value is empty, or whitespace
EmptyOrWhiteSpace(value) {
// replaces /n-s with "". then replaces spaces with "". if it equals "", then its empty, or only consists of white space
if (value === undefined)
return true;
return (value.replace(/\n/g, "").replace(/ /g, "").replace(/\s/g, ' ') === "");
}
// damn nonbreaking space
NormalizeSpaces(input) {
return input.replace(/\s/g, ' ');
}
CompareString(s1, s2) {
s1 = this.SimplifyStringForComparison(s1).split(" ");
s2 = this.SimplifyStringForComparison(s2).split(" ");
var match = 0;
for (var i = 0; i < s1.length; i++)
if (s2.includes(s1[i]))
match++;
var percent = Math.round(((match / s1.length) * 100).toFixed(2)); // matched words percent
var lengthDifference = Math.abs(s2.length - s1.length);
percent -= lengthDifference * lengthDiffMultiplier;
if (percent < 0)
percent = 0;
return percent;
}
}
class Question { class Question {
constructor(q, a, i) { constructor(q, a, i) {
this.Q = q; this.Q = q;
@ -68,13 +149,13 @@ class Question {
} }
Compare(q2, i) { Compare(q2, i) {
if (typeof q2 == 'string') { if (typeof q2 == 'string') {
var qmatchpercent = Question.CompareString(this.Q, q2); var qmatchpercent = SUtils.CompareString(this.Q, q2);
if (i == undefined || i.length == 0) if (i == undefined || i.length == 0)
return qmatchpercent; return qmatchpercent;
else { else {
if (this.HasImage()) { if (this.HasImage()) {
const imatchpercent = this.HasImage() ? Question.CompareString(this.I.join(" "), i.join(" ")) : const imatchpercent = this.HasImage() ? SUtils.CompareString(this.I.join(" "), i.join(" ")) :
0; 0;
return (qmatchpercent + imatchpercent) / 2; return (qmatchpercent + imatchpercent) / 2;
} else { } else {
@ -86,10 +167,10 @@ class Question {
} }
} }
} else { } else {
const qmatchpercent = Question.CompareString(this.Q, q2.Q); const qmatchpercent = SUtils.CompareString(this.Q, q2.Q);
const amatchpercent = Question.CompareString(this.A, q2.A); const amatchpercent = SUtils.CompareString(this.A, q2.A);
if (this.I != undefined) { if (this.I != undefined) {
const imatchpercent = this.I == undefined ? Question.CompareString(this.I.join(" "), q2.I.join( const imatchpercent = this.I == undefined ? SUtils.CompareString(this.I.join(" "), q2.I.join(
" ")) : 0; " ")) : 0;
return (qmatchpercent + amatchpercent + imatchpercent) / 3; return (qmatchpercent + amatchpercent + imatchpercent) / 3;
} else { } else {
@ -97,20 +178,6 @@ class Question {
} }
} }
} }
static CompareString(s1, s2) {
s1 = SimplifyStringForComparison(s1).split(" ");
s2 = SimplifyStringForComparison(s2).split(" ");
var match = 0;
for (var i = 0; i < s1.length; i++)
if (s2.includes(s1[i]))
match++;
var percent = Math.round(((match / s1.length) * 100).toFixed(2)); // matched words percent
var lengthDifference = Math.abs(s2.length - s1.length);
percent -= lengthDifference * lengthDiffMultiplier;
if (percent < 0)
percent = 0;
return percent;
}
} }
class Subject { class Subject {
@ -221,6 +288,9 @@ class QuestionDB {
return r.join("\n\n"); return r.join("\n\n");
} }
} }
var SUtils = new StringUtils();
//: }}} //: }}}
//: DOM getting stuff {{{ //: DOM getting stuff {{{
@ -282,13 +352,13 @@ class QuestionsPageModell {
if (allQuestions.length == 0) // if there are no found questions if (allQuestions.length == 0) // if there are no found questions
{ {
var ddq = this.GetAllQuestionsDropdown(); var ddq = this.GetAllQuestionsDropdown();
if (EmptyOrWhiteSpace(ddq)) { if (SUtils.EmptyOrWhiteSpace(ddq)) {
var questionData = ""; var questionData = "";
for (var j = 0; j < allQuestions.length; j++) { for (var j = 0; j < allQuestions.length; j++) {
// TODO: test dis // TODO: test dis
let subAllQuestions = allQuestions[j].childNodes; let subAllQuestions = allQuestions[j].childNodes;
for (var i = 0; i < subAllQuestions.length; i++) { for (var i = 0; i < subAllQuestions.length; i++) {
if (subAllQuestions[i].data != undefined && !EmptyOrWhiteSpace(subAllQuestions[i].data)) // if the current element has some text data to add if (subAllQuestions[i].data != undefined && !SUtils.EmptyOrWhiteSpace(subAllQuestions[i].data)) // if the current element has some text data to add
{ {
questionData += subAllQuestions[i].data + " "; // adding text to question data questionData += subAllQuestions[i].data + " "; // adding text to question data
} }
@ -317,7 +387,7 @@ class QuestionsPageModell {
} }
questions = questions.map((item, ind) => { questions = questions.map((item, ind) => {
return ReplaceCharsWithSpace(item, "\n"); return SUtils.ReplaceCharsWithSpace(item, "\n");
}); });
return { return {
@ -511,7 +581,7 @@ class ResultsPageModell {
for (var k = 0; k < allNodes.length; k++) { for (var k = 0; k < allNodes.length; k++) {
var allQuestions = this.GetResultText(i)[k].childNodes; var allQuestions = this.GetResultText(i)[k].childNodes;
for (var j = 0; j < allQuestions.length; j++) { for (var j = 0; j < allQuestions.length; j++) {
if (allQuestions[j].data != undefined && !EmptyOrWhiteSpace(allQuestions[j].data)) { if (allQuestions[j].data != undefined && !SUtils.EmptyOrWhiteSpace(allQuestions[j].data)) {
currQuestion += allQuestions[j].data + " "; currQuestion += allQuestions[j].data + " ";
} }
} }
@ -574,7 +644,7 @@ class ResultsPageModell {
var j = 0; var j = 0;
var currAnswer; var currAnswer;
while (j < fun.length && EmptyOrWhiteSpace(currAnswer)) { while (j < fun.length && SUtils.EmptyOrWhiteSpace(currAnswer)) {
currAnswer = fun[j](i); currAnswer = fun[j](i);
j++; j++;
} }
@ -826,7 +896,7 @@ function ReadFile(cwith) {
}); });
return; return;
} }
if (EmptyOrWhiteSpace(resource)) { if (SUtils.EmptyOrWhiteSpace(resource)) {
throw { throw {
message: "data file empty" message: "data file empty"
}; };
@ -1043,9 +1113,6 @@ function NLoad(resource, cwith) {
i++; i++;
} }
// TODO: move this
AlertOnNoQuestion(i);
} catch (e) { } catch (e) {
Exception(e, "script error at loading:"); Exception(e, "script error at loading:");
count = -1; // returns -1 if error count = -1; // returns -1 if error
@ -1053,9 +1120,8 @@ function NLoad(resource, cwith) {
cwith(count, subjCount); cwith(count, subjCount);
} }
var AlertOnNoQuestion = (i) => { var AlertOnNoQuestion = () => {
try { try {
if (i >= data.length)
document.getElementById("HelperMenuButton").style.background = "yellow"; document.getElementById("HelperMenuButton").style.background = "yellow";
} catch (e) { } catch (e) {
Log("Unable to get helper menu button"); Log("Unable to get helper menu button");
@ -1105,6 +1171,7 @@ function HandleUI(url, count, subjCount) {
if (toAdd.length != 0) { if (toAdd.length != 0) {
greetMsg += "\nAktív tárgyak: " + toAdd.join(", ") + "."; greetMsg += "\nAktív tárgyak: " + toAdd.join(", ") + ".";
} else { } else {
AlertOnNoQuestion();
greetMsg += "\nNincs aktív tárgyad. Menüből válassz ki eggyet!"; greetMsg += "\nNincs aktív tárgyad. Menüből válassz ki eggyet!";
timeout = undefined; timeout = undefined;
} }
@ -1127,7 +1194,7 @@ function HandleUI(url, count, subjCount) {
"-re. Changelog:\n" + lastChangeLog; "-re. Changelog:\n" + lastChangeLog;
GM_setValue("lastVerson", GM_info.script.version); // setting lastVersion GM_setValue("lastVerson", GM_info.script.version); // setting lastVersion
} }
if (!EmptyOrWhiteSpace(motd)) { if (!SUtils.EmptyOrWhiteSpace(motd)) {
var prevmotd = GM_getValue("motd"); var prevmotd = GM_getValue("motd");
if (prevmotd != motd) { if (prevmotd != motd) {
@ -1169,7 +1236,7 @@ function HandleQuiz() {
var answers = []; var answers = [];
for (var j = 0; j < questions.length; j++) // going thru all answers for (var j = 0; j < questions.length; j++) // going thru all answers
{ {
var question = RemoveUnnecesarySpaces(questions[j]); // simplifying question var question = SUtils.RemoveUnnecesarySpaces(questions[j]); // simplifying question
var result = data.Search(question, SimplifyImages(imgNodes)); var result = data.Search(question, SimplifyImages(imgNodes));
var r = PrepareAnswers(result, j); var r = PrepareAnswers(result, j);
if (r != undefined) if (r != undefined)
@ -1291,7 +1358,7 @@ function GetImageFormResult(i) {
{ {
var filePart = imgElements[j].src.split("/"); // splits the link by "/" var filePart = imgElements[j].src.split("/"); // splits the link by "/"
filePart = filePart[filePart.length - 1]; // the last one is the image name filePart = filePart[filePart.length - 1]; // the last one is the image name
imgURL.push(decodeURI(ShortenString(filePart, 30))); imgURL.push(decodeURI(SUtils.ShortenString(filePart, 30)));
} }
} }
if (imgURL.length > 0) { if (imgURL.length > 0) {
@ -1320,10 +1387,10 @@ function SaveQuiz(quiz, questionData) {
{ {
// searching for same questions in questionData // searching for same questions in questionData
var toAdd = ""; // this will be added to some variable depending on if its already in the database var toAdd = ""; // this will be added to some variable depending on if its already in the database
toAdd += "?" + RemoveUnnecesarySpaces(quiz[i].Q) + "\n"; // adding quiz question toAdd += "?" + SUtils.RemoveUnnecesarySpaces(quiz[i].Q) + "\n"; // adding quiz question
toAdd += "!" + RemoveUnnecesarySpaces(quiz[i].A) + "\n"; // adding quiz answer toAdd += "!" + SUtils.RemoveUnnecesarySpaces(quiz[i].A) + "\n"; // adding quiz answer
if (quiz[i].HasImage()) { if (quiz[i].HasImage()) {
toAdd += ">" + RemoveUnnecesarySpaces(quiz[i].I) + "\n"; // adding quiz image if there is any toAdd += ">" + SUtils.RemoveUnnecesarySpaces(quiz[i].I) + "\n"; // adding quiz image if there is any
} }
if (SearchSameQuestion(questionData, quiz, i) == -1) // if there is no such item in the database (w/ same q and a) if (SearchSameQuestion(questionData, quiz, i) == -1) // if there is no such item in the database (w/ same q and a)
{ {
@ -1372,22 +1439,22 @@ function GetQuiz() {
// QUESTION -------------------------------------------------------------------------------------------------------------------- // QUESTION --------------------------------------------------------------------------------------------------------------------
var q = RPM.GetQuestionFromResult(i); var q = RPM.GetQuestionFromResult(i);
if (q != undefined) if (q != undefined)
question.q = SimplifyQuery(q); question.q = SUtils.SimplifyQuery(q);
// RIGHTANSWER --------------------------------------------------------------------------------------------------------------------- // RIGHTANSWER ---------------------------------------------------------------------------------------------------------------------
var a = RPM.GetRightAnswerFromResultv2(i); var a = RPM.GetRightAnswerFromResultv2(i);
if (a == undefined) if (a == undefined)
a = RPM.GetRightAnswerFromResult(i); a = RPM.GetRightAnswerFromResult(i);
if (a != undefined) if (a != undefined)
question.a = SimplifyQuery(a); question.a = SUtils.SimplifyQuery(a);
// IMG --------------------------------------------------------------------------------------------------------------------- // IMG ---------------------------------------------------------------------------------------------------------------------
var img = GetImageFormResult(i); var img = GetImageFormResult(i);
question.i = img; question.i = img;
if (q != undefined) if (q != undefined)
q = ReplaceCharsWithSpace(q, "\n"); q = SUtils.ReplaceCharsWithSpace(q, "\n");
if (a != undefined) if (a != undefined)
a = ReplaceCharsWithSpace(a, "\n"); a = SUtils.ReplaceCharsWithSpace(a, "\n");
if (question.a != undefined) // adding only if has question if (question.a != undefined) // adding only if has question
{ {
@ -1416,7 +1483,7 @@ function SimplifyImages(imgs) {
{ {
var filePart = imgs[i].src.split("/"); // splits the link by "/" var filePart = imgs[i].src.split("/"); // splits the link by "/"
filePart = filePart[filePart.length - 1]; // the last one is the image name filePart = filePart[filePart.length - 1]; // the last one is the image name
questionImages.push(decodeURI(RemoveUnnecesarySpaces(ShortenString(filePart, 30)))); // decodes uri codes, and removes exess spaces, and shortening it questionImages.push(decodeURI(SUtils.RemoveUnnecesarySpaces(SUtils.ShortenString(filePart, 30)))); // decodes uri codes, and removes exess spaces, and shortening it
} }
} }
return questionImages; return questionImages;
@ -1432,7 +1499,7 @@ function AddImageNamesToImages(imgs) {
filePart = filePart[filePart.length - 1]; // the last one is the image name filePart = filePart[filePart.length - 1]; // the last one is the image name
var appedtTo = imgs[i].parentNode; // it will be appended here var appedtTo = imgs[i].parentNode; // it will be appended here
var mainDiv = document.createElement("div"); var mainDiv = document.createElement("div");
var fileName = ShortenString(decodeURI(filePart), 15); // shortening name, couse it can be long as fuck var fileName = SUtils.ShortenString(decodeURI(filePart), 15); // shortening name, couse it can be long as fuck
var textNode = document.createTextNode("(" + fileName + ")"); var textNode = document.createTextNode("(" + fileName + ")");
mainDiv.appendChild(textNode); mainDiv.appendChild(textNode);
appedtTo.appendChild(mainDiv); appedtTo.appendChild(mainDiv);
@ -1477,7 +1544,7 @@ function AddVideoHotkeys(url) {
} }
function GetMatchPercent(currData, questionParts) { function GetMatchPercent(currData, questionParts) {
var currQuestion = SimplifyQuery(currData.q); // current question simplified var currQuestion = SUtils.SimplifyQuery(currData.q); // current question simplified
var match = 0; // how many times the current question matches the current question in the database var match = 0; // how many times the current question matches the current question in the database
for (var i = 0; i < questionParts.length; i++) // going through the question parts for (var i = 0; i < questionParts.length; i++) // going through the question parts
{ {
@ -1487,7 +1554,7 @@ function GetMatchPercent(currData, questionParts) {
} }
} }
var percent = Math.round(((match / questionParts.length) * 100).toFixed(2)); // matched words percent var percent = Math.round(((match / questionParts.length) * 100).toFixed(2)); // matched words percent
var lengthDifference = RemoveMultipleItems(SimplifyQuery(currQuestion).split(" ")).length - var lengthDifference = RemoveMultipleItems(SUtils.SimplifyQuery(currQuestion).split(" ")).length -
questionParts.length; questionParts.length;
percent -= Math.abs(lengthDifference) * 2; percent -= Math.abs(lengthDifference) * 2;
return percent; return percent;
@ -1514,9 +1581,9 @@ function RemoveLetterMarking(inp) {
let maxInd = 4; // inp.length * 0.2; let maxInd = 4; // inp.length * 0.2;
if (dotIndex < maxInd) if (dotIndex < maxInd)
return RemoveUnnecesarySpaces(inp.substr(inp.indexOf(".") + 1, inp.length)); return SUtils.RemoveUnnecesarySpaces(inp.substr(inp.indexOf(".") + 1, inp.length));
else if (doubledotIndex < maxInd) else if (doubledotIndex < maxInd)
return RemoveUnnecesarySpaces(inp.substr(inp.indexOf(":") + 1, inp.length)); return SUtils.RemoveUnnecesarySpaces(inp.substr(inp.indexOf(":") + 1, inp.length));
else else
return inp; return inp;
} }
@ -1539,10 +1606,10 @@ function HighLightAnswer(results, currQuestionNumber) {
// removing stuff like "a." // removing stuff like "a."
answer = RemoveLetterMarking(answer); answer = RemoveLetterMarking(answer);
if (EmptyOrWhiteSpace(correct) || EmptyOrWhiteSpace(answer)) if (SUtils.EmptyOrWhiteSpace(correct) || SUtils.EmptyOrWhiteSpace(answer))
continue; continue;
if (NormalizeSpaces(RemoveUnnecesarySpaces(correct)).includes(answer)) // if the correct answer includes the current answer if (SUtils.NormalizeSpaces(SUtils.RemoveUnnecesarySpaces(correct)).includes(answer)) // if the correct answer includes the current answer
{ {
toColor.push(i); // adding the index toColor.push(i); // adding the index
type = MPM.GetInputType(answers, i); // setting the type type = MPM.GetInputType(answers, i); // setting the type
@ -2164,22 +2231,6 @@ function RemoveMultipleItems(array) {
return newArray; return newArray;
} }
// removes some crap from "q"
function SimplifyQuery(q) {
var result = q.replace(/\n/g, " ").replace(/\s/g, ' '); // WHY TF ARE THERE TWO KINDA SPACES??? (charcode 160 n 32)
return RemoveUnnecesarySpaces(result);
}
function ShortenString(toShorten, ammount) {
var result = "";
var i = 0;
while (i < toShorten.length && i < ammount) {
result += toShorten[i];
i++;
}
return result;
}
function CreateNodeWithText(to, text, type) { function CreateNodeWithText(to, text, type) {
var paragraphElement = document.createElement(type || "p"); // new paragraph var paragraphElement = document.createElement(type || "p"); // new paragraph
var textNode = document.createTextNode(text); var textNode = document.createTextNode(text);
@ -2188,53 +2239,6 @@ function CreateNodeWithText(to, text, type) {
return paragraphElement; return paragraphElement;
} }
function ReplaceCharsWithSpace(val, char) {
assert(val);
assert(char);
toremove = NormalizeSpaces(val);
var regex = new RegExp(char, "g");
toremove.replace(regex, " ");
return RemoveUnnecesarySpaces(toremove);
}
// removes whitespace from begining and and, and replaces multiple spaces with one space
function RemoveUnnecesarySpaces(toremove) {
toremove = NormalizeSpaces(toremove);
while (toremove.includes(" ")) // while the text includes double spaces replaces all of them with a single one
{
toremove = toremove.replace(/ /g, " ");
}
return toremove.trim();
}
// simplifies a string for easier comparison
function SimplifyStringForComparison(value) {
value = RemoveUnnecesarySpaces(value).toLowerCase();
var removableChars = [",", ".", ":", "!"];
for (var i = 0; i < removableChars.length; i++) {
var regex = new RegExp(removableChars[i], "g");
value.replace(regex, "");
}
return value;
}
// if the value is empty, or whitespace
function EmptyOrWhiteSpace(value) {
// replaces /n-s with "". then replaces spaces with "". if it equals "", then its empty, or only consists of white space
if (value === undefined)
return true;
return (value.replace(/\n/g, "").replace(/ /g, "").replace(/\s/g, ' ') === "");
}
// damn nonbreaking space
function NormalizeSpaces(input) {
return input.replace(/\s/g, ' ');
}
function SendXHRMessage(message) { function SendXHRMessage(message) {
var url = serverAdress + "isAdding"; var url = serverAdress + "isAdding";
GM_xmlhttpRequest({ GM_xmlhttpRequest({